原文鏈接http://zhhll.icu/2020/07/26/%E6%A1%86%E6%9E%B6/spring/Spring%20AOP/
AOP稱為切面編程,是面向物件的一種補充,用于處理系統中分布于各個模塊的橫切關注點,比如事務管理、日志、快取等,Spring AOP中使用的是動態代理,
Spring AOP
動態代理不會去修改位元組碼,而是在記憶體中臨時為方法生成一個AOP物件,這個AOP物件包含了目標物件的全部方法,并且在特定的切點做了增強處理,并回呼原物件的方法,
AOP的核心是切面,它將多個類的通用行為封裝成可重用的模塊,該模塊含有一組API提供橫切的功能,在SpringAOP中,切面通過@Aspect注解,也可以使用XML配置
AOP動態代理方式
Spring AOP中動態代理主要有兩種方式,JDK動態代理和CGLIB動態代理,
JDK動態代理
JDK動態代理通過反射來接收被代理的類,并且要求被代理的類必須實作一個介面,JDK代理的核心是InvocationHandler介面和Proxy類,
CGLIB代理
如果目標類沒有實作介面,那么Spring AOP會使用CGLIB代理來動態代理目標類,CGLIB是一個代碼生成的類別庫,可以在運行時動態的生成某個類的子類(通過繼承的方式做的動態代理,如果某個類被標記為final,無法使用CGLIB做動態代理)
AOP中的概念
- 橫切關注點 從每個方法中抽取出來的非核心業務
- 切面(Aspect) 封裝橫切關注點的類,被模塊化的特殊物件,每個關注點體現為一個通知
- 通知(Advice) 切面需要完成的各個具體作業
- 目標(Target) 被通知的物件
- 代理(Proxy) 向目標物件應用通知之后創建的物件
- 連接點(Joinpoint) 橫切關注點的具體體現,程式執行的某個特定位置:比如呼叫前、呼叫后、拋出例外后
- 切點(pointCut) 每個類都有多個連接點,AOP通過切點來定位到特定的連接點
有五種型別的AOP通知
-
before 前置通知,在方法執行之前被呼叫 @Before
-
after 后置通知,在方法執行之后呼叫,無論方法執行是否成功,所以后置通知無法獲取到回傳結果@After
-
after-returning 僅當方法成功完成后執行@AfterReturning
-
after-throwing 在方法拋出例外退出時執行@AfterThrowing
-
around 在方法執行之前和之后呼叫@Around
AOP使用方式
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="https://www.cnblogs.com/life-time/p/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="https://www.cnblogs.com/life-time/p/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
使用XML
所有的aop配置都應該配置在<aop:config>標簽中,在xml中只需要關注切面、通知以及切入點運算式
<!-- LoggingAspect所對應的bean -->
<bean name="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
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/264055.html
標籤:Java
上一篇:對稱加密、非對稱加密、數字簽名
