原文連接http://zhhll.icu/2020/07/26/%E6%A1%86%E6%9E%B6/spring/Spring%20AOP/java
AOP稱爲切面編程,是面向對象的一種補充,用於處理系統中分佈於各個模塊的橫切關注點,好比事務管理、日誌、緩存等。Spring AOP中使用的是動態代理。spring
動態代理不會去修改字節碼,而是在內存中臨時爲方法生成一個AOP對象,這個AOP對象包含了目標對象的所有方法,而且在特定的切點作了加強處理,並回調原對象的方法。express
AOP的核心是切面,它將多個類的通用行爲封裝成可重用的模塊,該模塊含有一組API提供橫切的功能,在SpringAOP中,切面經過@Aspect註解,也可使用XML配置編程
Spring AOP中動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理。緩存
JDK動態代理經過反射來接收被代理的類,而且要求被代理的類必須實現一個接口,JDK代理的核心是InvocationHandler接口和Proxy類。模塊化
若是目標類沒有實現接口,那麼Spring AOP會使用CGLIB代理來動態代理目標類。CGLIB是一個代碼生成的類庫,能夠在運行時動態的生成某個類的子類(經過繼承的方式作的動態代理,若是某個類被標記爲final,沒法使用CGLIB作動態代理)代理
有五種類型的AOP通知日誌
before 前置通知,在方法執行以前被調用 @Beforecode
after 後置通知,在方法執行以後調用,不管方法執行是否成功,因此後置通知沒法獲取到返回結果@Afterxml
after-returning 僅當方法成功完成後執行@AfterReturning
after-throwing 在方法拋出異常退出時執行@AfterThrowing
around 在方法執行以前和以後調用@Around
AOP所須要的依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.3.29.RELEASE</version> </dependency> <!-- aspect --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.29.RELEASE</version> </dependency>
使用註解的時候須要在xml中配置aop:aspectj-autoproxy/
<!-- 使@Aspect註解生效 --> <aop:aspectj-autoproxy/>
/** * 聲明切面 */ @Aspect @Component @Order(1)// 使用Order指定切面優先級 數字越小 優先級越高 越先執行 public class LoggingAspect { // @Before 前置通知 // JoinPoint 能夠獲取到方法的一些信息 @Before("execution(public String com.zhanghe.study.spring4.beans.aoptest.MyInterface.log(..))") public void before(JoinPoint point){ // 獲取方法名 String methodName = point.getSignature().getName(); // point.getArgs()獲取參數 System.out.println(methodName+"方法執行前,參數爲"+ Arrays.toString(point.getArgs())); } // 方法正常執行完,能夠獲取方法返回值 // returning中配置的名字必須與第二個參數同名 @AfterReturning(value="execution(public String com.zhanghe.study.spring4.beans.aoptest.MyInterface.log(..))", returning = "result") public void afterReturn(JoinPoint point,Object result){ // 獲取方法名 String methodName = point.getSignature().getName(); System.out.println(methodName+"方法執行完成,結果爲"+ result); } // 方法出現異常 // throwing中配置的名字必須與第二個參數同名,且能夠指定對於哪些異常進行執行 第二個參數類型能夠爲所要捕獲的異常類型 @AfterThrowing(value="execution(public String com.zhanghe.study.spring4.beans.aoptest.MyInterface.log(..))", throwing = "exception") public void afterThrowing(JoinPoint point,Exception exception){ // 獲取方法名 String methodName = point.getSignature().getName(); System.out.println(methodName+"方法執行出現異常,異常信息爲"+ exception.getMessage()); } }
在使用切面的時候必須保證切面是Spring IOC容器中的bean
全部的aop配置都應該配置在<aop:config>標籤中,在xml中只須要關注切面、通知以及切入點表達式
<!-- LoggingAspect所對應的bean --> <bean name="loggingAspect" class="com.zhanghe.study.spring4.beans.aoptest.LoggingAspect"/> <!-- 配置AOP --> <aop:config> <!-- 配置切點表達式 --> <aop:pointcut id="pointcut" expression="execution(public String com.zhanghe.study.spring4.beans.aoptest.MyInterface.log(..)))"/> <!-- 配置切面及通知 --> <aop:aspect ref="loggingAspect" order="1"> <!-- 通知 --> <aop:before method="before" pointcut-ref="pointcut"/> <aop:after-returning method="afterReturn" returning="result" pointcut-ref="pointcut"/> <aop:after-throwing method="afterThrowing" throwing="exception" pointcut-ref="pointcut"/> </aop:aspect> </aop:config>
注意:使用xml的模式進行配置記得保證切面是Spring IOC容器中的bean
因爲自己的博客百度沒有收錄,博客地址http://zhhll.icu