-
介紹
- AspectJ是一個基於Java語言的AOP框架
- Spring2.0以後新增了對AspectJ切點表達支援
- @AspectJ是AspectJ1.5新增功能,通過JDK5註解技術,允許Bean類中定義切面,新版本Spring框架,建議使用AspectJ方式來開發AOP
- 主要用途:自定義開發
-
切入點表示式
-
execution() 用於描述方法
<!--建立目標類--> <bean id="userService" class="com.adolph.AOP.jdk.UserServiceImpl"></bean> <!--建立切面類--> <bean id="myAspect" class="com.adolph.AOP.jdk.MyAspect"></bean> <!--aop程式設計 使用<aop:config>進行配置 proxy-target-class="true":使用cglib代理 <aop:pointcut>切入點,從目標物件獲得具體方法 <aop:advisor> 特殊的切面,只有一個通知和一個切入點 advice-ref:通知引用 pointcut-ref:切入點引用 切入點表示式: execution(* com.adolph.AOP.jdk.*.*(..)) 選擇方法 返回值任意 包 類名任意 方法名任意 引數任意 --> <aop:config proxy-target-class="true"> <aop:pointcut id="myPointCut" expression="execution(* com.adolph.AOP.jdk.*.*(..))"/> <aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"/> </aop:config> 複製程式碼
-
語法:execution(修飾符 返回值 包.類.方法(引數) throws 異常)
- 修飾符:一般省略
- 返回值:*(任意)
- 包
- 省略
- con.adolph.cn 固定包
- com.adolph. adolph包下面子包任意*
- com.adolph.. adolph包下面的所有子包(含自己)
- 省略
- 類
- 省略
- UserServiceImpl 指定類
- *Impl 以Impl結尾
- User 以User開頭*
- *. 任意
- 方法名
- 不能省略
- addUser 固定方法
- add 以add開頭*
- *Do 以Do結尾
- *. 任意
- 引數
- () 無參
- (int) 一個整型
- (int,int) 兩個
- (..) 引數任意
- throws
- 可省略,一般不寫
-
綜合
`execution(* com.adolph.AOP.jdk.*.*(..))` 複製程式碼
-
-
-
AspectJ通知型別
- aop聯盟定義通知型別,具有特性介面,必須實現,從而確定方法名稱
- aspectj 通知型別,只定義型別名稱。以及方法格式
- 個數:6種,知道5種,掌握一種
- before:前置通知
- afterReturning:後置通知(應用:常規資料處理)
- around:環繞通知(應用:十分強大,可以做任何事情)
- 方法執行前後分別執行、可以阻止方法的執行
- 必須手動執行目標方法
- afterThrowing:丟擲異常通知(應用:包裝異常資訊)
- after:最終通知(應用:清理現場)
-
基於XML
-
目標類:介面+實現
-
切面類:編寫多個通知,採用aspectJ通知名稱任意(方法名任意)
-
aop程式設計:將通知應用到目標類
-
測試
-
目標類
public class UserServiceImpl { public void addUser() { System.out.println("addUser"); } public void updateUser() { System.out.println("updateUser"); } public void deleteUser() { System.out.println("deleteUser"); } } 複製程式碼
-
切面類
/** * 切面類,含有多個通知 */ public class MyAspect { public void myBefore(JoinPoint joinPoint) { System.out.println("前置通知" + joinPoint.getSignature().getName()); //獲得目標方法名 } public void myAfterReturning(JoinPoint joinPoint, Object ret) { System.out.println("後置通知" + joinPoint.getSignature().getName() + "____" + ret); //獲得目標方法名 } public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("前"); //手動執行目標方法 Object proceed = joinPoint.proceed(); System.out.println("後"); return proceed; } public void MyAfterThrowing(JoinPoint joinPoint,Throwable e){ System.out.println("丟擲異常通知:"); } public void after(JoinPoint joinPoint){ System.out.println("最終"); } } 複製程式碼
-
xml
<!--建立目標類--> <bean id="userService" class="com.adolph.AOP.jdk.UserServiceImpl"></bean> <!--建立切面類--> <bean id="myAspect" class="com.adolph.AOP.jdk.MyAspect"></bean> <!--aop程式設計 --> <aop:config> <!--將切面類 宣告成切面,從而獲得通知(方法),ref:切面類引用--> <aop:aspect ref="myAspect"> <!--宣告一個切入點,所有的通知都可以使用 expression:切入點表示式 id:名稱用於其他通知引用 --> <aop:pointcut id="myPointcut" expression="execution(* com.adolph.AOP.jdk.UserServiceImpl.*(..))"></aop:pointcut> <!--前置通知 method:通知,及方法名 pointcut:切入點表示式,此表示式只能當前通知使用 pointcut-ref:切入點引用,可以與其他通知點共享切入點 通知方法格式:public void myBefore(JoinPoint joinPoint) 引數JoinPoint 用於描述連線點(目標方法),獲得目標方法名稱等 --> <aop:before method="myBefore" pointcut-ref="myPointcut"></aop:before> <!--後置通知,目標方法執行,獲得返回值 public void myAfterReturning(JoinPoint joinPoint,Object ret) 引數1:連線點描述 引數2:型別Object,引數名returning配置的 --> <aop:after-returning method="myAfterReturning" pointcut-ref="myPointcut" returning="ret"></aop:after-returning> <!--環繞通知 public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable 返回值:Object 方法名:任意 引數:Proceeding JoinPoint 丟擲異常 --> <aop:around method="myAround" pointcut-ref="myPointcut"></aop:around> <!--異常通知 throwing:通知方法的第二個引數名稱 --> <aop:after-throwing method="MyAfterThrowing" pointcut-ref="myPointcut" throwing="e"></aop:after-throwing> <!--最終通知--> <aop:after method="after" pointcut-ref="myPointcut"></aop:after> </aop:aspect> </aop:config> 複製程式碼
-
-
基於註解
-
替換bean
<!--掃描--> <context:component-scan base-package="com.adolph.AOP"></context:component-scan> 複製程式碼
@Component public class MyAspect 複製程式碼
-
必須進行aspectj自動代理
<!--確定aop註解生效--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 複製程式碼
-
宣告切面
@Component @Aspect public class MyAspect 複製程式碼
-
設定前置通知
@Before("execution(* com.adolph.AOP.jdk.UserServiceImpl.*(..))") public void myBefore(JoinPoint joinPoint) { System.out.println("前置通知" + joinPoint.getSignature().getName()); //獲得目標方法名 } 複製程式碼
-
替換公共切入點
@Pointcut("execution(* com.adolph.AOP.jdk.UserServiceImpl.*(..))") private void myPointCut(){ } 複製程式碼
-
設定後置通知
@AfterReturning(value = "myPointCut()",returning = "ret") public void myAfterReturning(JoinPoint joinPoint, Object ret) { System.out.println("後置通知" + joinPoint.getSignature().getName() + "____" + ret); //獲得目標方法名 } 複製程式碼
-
設定環繞通知
@Around(value = "myPointCut()") public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{ System.out.println("前"); //手動執行目標方法 Object proceed = joinPoint.proceed(); System.out.println("後"); return proceed; } 複製程式碼
-
設定丟擲異常
@AfterThrowing(value = "myPointCut()",throwing = "e") public void MyAfterThrowing(JoinPoint joinPoint,Throwable e){ System.out.println("丟擲異常通知:"); } 複製程式碼
-
最終通知
@AfterThrowing(value = "myPointCut()",throwing = "e") public void MyAfterThrowing(JoinPoint joinPoint,Throwable e){ System.out.println("丟擲異常通知:"); } 複製程式碼
-
AspectJ學習筆記
相關文章
- numpy的學習筆記\pandas學習筆記筆記
- 學習筆記筆記
- 【學習筆記】數學筆記
- 《JAVA學習指南》學習筆記Java筆記
- 機器學習學習筆記機器學習筆記
- 學習筆記-粉筆980筆記
- 學習筆記(3.29)筆記
- 學習筆記(4.1)筆記
- 學習筆記(3.25)筆記
- 學習筆記(3.26)筆記
- JavaWeb 學習筆記JavaWeb筆記
- golang 學習筆記Golang筆記
- Nginx 學習筆記Nginx筆記
- spring學習筆記Spring筆記
- gPRC學習筆記筆記
- GDB學習筆記筆記
- 學習筆記(4.2)筆記
- 學習筆記(4.3)筆記
- 學習筆記(4.4)筆記
- Servlet學習筆記Servlet筆記
- 學習筆記(3.27)筆記
- jest 學習筆記筆記
- NodeJS學習筆記NodeJS筆記
- WebSocket 學習筆記Web筆記
- mount 學習筆記筆記
- mapGetters學習筆記筆記
- jQuery學習筆記jQuery筆記
- 學習筆記:DDPG筆記
- flex學習筆記Flex筆記
- react 學習筆記React筆記
- Promise學習筆記Promise筆記
- vim學習筆記筆記
- Ansible 學習筆記筆記
- Taro 學習筆記筆記
- MongoDB學習筆記MongoDB筆記
- hbase學習筆記筆記
- git學習筆記Git筆記
- ComfyUi學習筆記UI筆記