通知分爲前置通知、後置通知、異常通知、後置返回通知、環繞通知
其中環繞通知中相當於包含了前置通知、後置通知、異常通知 外加一個最終通知
直接上代碼
pom文件中導包
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.9.RELEASE</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.4</version> </dependency> </dependencies>
接口中的三個方法
public interface IAccountService {
void saveAccount();
void updateAccount(int i,int j);
int deleteAccount();
}
實現類中的三個方法
public class AccountServiceImpl implements IAccountService {
public void saveAccount() {
System.out.println("保存賬戶信息");
}
public void updateAccount(int i,int j) {
int m= 1/0; //測試異常通知時可以解開註釋
System.out.println("修改金額:"+i);
}
public int deleteAccount() {
System.out.println("刪除賬戶");
return 0;
}
}
工具Logger中增加一個通知方法
public class Logger {
public void beforePrintLogger(){
System.out.println("前置通知打印日誌。。。");
}
public void afterPrintLogger(){
System.out.println("後置通知打印日誌。。。");
}
public void retrunPrintLogger(){
System.out.println("返回通知通知打印日誌。。。");
}
public void exceptionPrintLogger(){
System.out.println("異常通知打印日誌。。。");
}
public Object aroundPrintLogger(ProceedingJoinPoint pjp){
Object rtValue=null;
try {
System.out.println("環繞通知打印日誌。。。業務方法執行前的代碼相當於前置通知");
Object[] args=pjp.getArgs();
rtValue = pjp.proceed(args);
System.out.println("環繞通知打印日誌。。。業務方法執行厚的代碼相當於後置通知");
return rtValue;
} catch (Throwable throwable) { //這裏的異常類型必須是Throwable類型
System.out.println("環繞通知打印日誌。。。這裏相當於異常通知");
throw new RuntimeException(throwable);
}
finally {
System.out.println("環繞通知打印日誌。。。這裏相當於返回通知");
}
}
}
配置Bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="accountService" class="com.itheima.aop.AccountServiceImpl"></bean>
<bean id="logger" class="com.itheima.utils.Logger"></bean>
<!--com.itheima.aop.AccountServiceImpl.saveAccount()-->
<aop:config>
<!--pointcut可以放置到切面外所喲切面均可引用,但必須放到引用他的切面的最上邊-->
<aop:pointcut id="accountPoint" expression="execution(* *..*(int,int))"></aop:pointcut>
<aop:aspect id="logAdvicer" ref="logger">
<aop:before method="beforePrintLogger" pointcut="execution(* *..*(int,int))"></aop:before>
<aop:after method="afterPrintLogger" pointcut-ref="accountPoint"></aop:after>
<aop:after-returning method="retrunPrintLogger" pointcut-ref="accountPoint"></aop:after-returning>
<aop:after-throwing method="exceptionPrintLogger" pointcut-ref="accountPoint"></aop:after-throwing>
<aop:around method="aroundPrintLogger" pointcut-ref="accountPoint"></aop:around>
<!--pointcut可以放置在切面內,此時只能當前切面內引用-->
<!--<aop:pointcut id="accountPoint" expression="execution(* *..*(int,int))"></aop:pointcut>-->
</aop:aspect>
</aop:config>
</beans>
測試類
public class Client {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("Bean.xml");
IAccountService accountService = (IAccountService)ac.getBean("accountService");
// accountService.saveAccount();
accountService.updateAccount(1,2);
// accountService.deleteAccount();
}
}