1. 簡介Spring AOP是Spring框架的一個重要組成部分,它允許開發(fā)者定義跨多個模塊的橫切關(guān)注點,例如日志記錄、事務管理、安全等。控制流切入和引" />

日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

漲知識!Spring AOP還能這么玩,看看你的項目能否用上

來源: 責編: 時間:2024-01-02 09:31:49 213觀看
導讀環(huán)境:Spring5.3.23本篇文章將介紹兩個主題:控制流切入點(動態(tài)切入點)引介通知
1. 簡介Spring AOP是Spring框架的一個重要組成部分,它允許開發(fā)者定義跨多個模塊的橫切關(guān)注點,例如日志記錄、事務管理、安全等。控制流切入和引

環(huán)境:Spring5.3.231s828資訊網(wǎng)——每日最新資訊28at.com

本篇文章將介紹兩個主題:1s828資訊網(wǎng)——每日最新資訊28at.com

  • 控制流切入點(動態(tài)切入點)
  • 引介通知

1. 簡介

Spring AOP是Spring框架的一個重要組成部分,它允許開發(fā)者定義跨多個模塊的橫切關(guān)注點,例如日志記錄、事務管理、安全等。控制流切入和引介通知是Spring AOP中的兩個關(guān)鍵特性,它們能夠增強程序的可維護性和可讀性。本文將深入探討這兩個特性的工作原理和使用方法。1s828資訊網(wǎng)——每日最新資訊28at.com

控制流切入

控制流切入允許我們根據(jù)方法調(diào)用的控制流來定義切入點。控制流切入點與當前調(diào)用堆棧匹配。例如,如果連接點被com.pack.service包中的方法或PersonService類調(diào)用,它可能會觸發(fā)。控制流切入點是通過使用org.springframework.aop.support.ControlFlowPointcut類指定的。1s828資訊網(wǎng)——每日最新資訊28at.com

引介通知

引介通知能夠聲明被建議的對象實現(xiàn)給定的接口,并代表這些對象提供該接口的實現(xiàn)。簡單說:你有個PersonService類,引介通知能夠讓你不修改代碼的情況下去實現(xiàn)你給定的任意接口(CommonDAO)。1s828資訊網(wǎng)——每日最新資訊28at.com

2. 實戰(zhàn)案例

2.1 控制流切入點

準備基礎(chǔ)類

@Componentpublic class PersonDAO {  public void save(String name) {    System.out.println("PersonDAO save method invoke...") ;  }}@Componentpublic class PersonService {  @Resource  private PersonDAO dao ;  public void save(String name) {    System.out.println("PersonService save method inovke...") ;    this.dao.save(name) ;  }}

定義切面類Advisor

低級切面Advisor,平時使用的@Aspect算是高級切面類,而這些高級切面類最終會被轉(zhuǎn)換為Advisor低級切面類。1s828資訊網(wǎng)——每日最新資訊28at.com

@Componentpublic class PackControlFlowAdvisor extends DefaultPointcutAdvisor {  private static MethodInterceptor logInterceptor = invocation -> {    System.out.println("before log...") ;    Object ret = invocation.proceed() ;    System.out.println("after log...") ;    return ret ;  } ;  // 要進行匹配的類  private static Class<?> clazz = PersonService.class ;  // 要進行匹配的方法(可以為null,這樣指定類中的所有方法都會被匹配攔截)  private static String methodName = "save" ;  private static ControlFlowPointcut pointcut = new ControlFlowPointcut(clazz, methodName) ;  public PackControlFlowAdvisor() {    super(pointcut, logInterceptor) ;  }}

測試1s828資訊網(wǎng)——每日最新資訊28at.com

PersonService ps = context.getBean(PersonService.class) ;ps.save("王五") ;

控制臺輸出1s828資訊網(wǎng)——每日最新資訊28at.com

PersonService save method inovke...before log...PersonDAO save method invoke...after log...

PersonDAO中的save方法被攔截了。什么意思?怎么PersonDAO就被攔截了,先來看上面切點的定義ControlFlowPointcut1s828資訊網(wǎng)——每日最新資訊28at.com

public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher {  public boolean matches(Class<?> clazz) {    return true;  }  public boolean matches(Method method, Class<?> targetClass) {    return true;  }  public boolean isRuntime() {    return true;  }  public boolean matches(Method method, Class<?> targetClass, Object... args) {    // 取得當前線程的整個執(zhí)行棧(方法的調(diào)用)    for (StackTraceElement element : new Throwable().getStackTrace()) {      if (element.getClassName().equals(this.clazz.getName()) &&          (this.methodName == null || element.getMethodName().equals(this.methodName))) {        return true;      }    }    return false;  }}

通過在這個切點類能知道:1s828資訊網(wǎng)——每日最新資訊28at.com

  1. 當前容器中的所有類都會被代理;因為這里的類匹配直接返回true,2個參數(shù)的matches直接返回true,最后isRuntime返回true,最終執(zhí)行3個參數(shù)的matches方法。
  2. 每個類中方法的調(diào)用都會獲取當前執(zhí)行的棧,都會進行判斷類及方法是否被匹配。

結(jié)合上面的測試輸出結(jié)果,PersonDAO#save方法被攔截了,因為它符合匹配條件,在PersonService#save方法中調(diào)用了PersonDAO#save方法,那PersonDAO#save方法執(zhí)行棧中就包含了PersonService#save正好匹配了我們定義的切點。1s828資訊網(wǎng)——每日最新資訊28at.com

簡單說:某個類中的某個方法調(diào)用時會判斷當前整個執(zhí)行棧中是否有設定好的類及方法,如果有則攔截當前的方法(執(zhí)行通知)。
1s828資訊網(wǎng)——每日最新資訊28at.com

注意:控制流切入點比正常切入點慢10-15倍,但在某些情況下它們是有用的。所以大家還是慎重使用吧,畢竟所有的類都被代理了(當然這里我們可以自定義matches來控制)。1s828資訊網(wǎng)——每日最新資訊28at.com

2.2 引介通知

引介通知相對比較簡單直接可以在@Aspect切面類中定義1s828資訊網(wǎng)——每日最新資訊28at.com

注備基礎(chǔ)類

// 這個接口是我們準備讓其它類實現(xiàn)的public interface CommonManager {  void calc(int a, int b) ;}// 默認實現(xiàn)public class DefaultCommonManager implements CommonManager {  @Override  public void calc(int a, int b) {    System.out.printf("計算a + b = %d%n", (a + b)) ;  }}// 該類是我們將要通過引介增強讓其實現(xiàn)CommonManager類@Component("us")public class UserService {  public void save() {    System.out.println("UserService save...") ;  }}

切面類1s828資訊網(wǎng)——每日最新資訊28at.com

@Aspectpublic static class CommonAspect {  /**   * 這樣聲明后,匹配的類就會自動的實現(xiàn)這里指定的CommonManager接口,默認的實現(xiàn)類是使用DefaultCommonManager   * value:該值決定了哪些類會被增強(實現(xiàn)指定的CommonManager接口)   */  @DeclareParents(value = "com.pack.main.aop_introductionadviser.IntructionDeclareMain2.*+", defaultImpl = DefaultCommonManager.class)  public static CommonManager mixin;}

注意:在這個切面類中我們并沒有定義@Before,@Around等同志。1s828資訊網(wǎng)——每日最新資訊28at.com

測試
1s828資訊網(wǎng)——每日最新資訊28at.com

CommonManager c = (CommonManager) context.getBean("us") ;c.calc(10, 20) ;

控制臺輸出1s828資訊網(wǎng)——每日最新資訊28at.com

計算a + b = 30

UserService能正確的轉(zhuǎn)換為CommonManager類,這說明UserService生成的代理類實現(xiàn)了CommonManager接口類,同時在執(zhí)行方法調(diào)用的時候使用的是我們制定的默認實現(xiàn)類DefaultCommonManager。1s828資訊網(wǎng)——每日最新資訊28at.com

總結(jié):控制流切入點(ControlFlowPointcut)和引介通知(@DeclareParents)是Spring AOP的兩個重要概念。控制流切入點用于在特定的控制流條件下切入代碼,而引介通知則讓目標類具有更加強大的能力。1s828資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-55297-0.html漲知識!Spring AOP還能這么玩,看看你的項目能否用上

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 代碼分析利器,你值得擁有

下一篇: 漲知識!Spring AOP還能這么玩,看看你的項目能否用上

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 呼图壁县| 黎川县| 荔波县| 龙海市| 鄂伦春自治旗| 沅陵县| 广安市| 富民县| 巴林左旗| 太仓市| 天镇县| 固原市| 临夏县| 海原县| 新郑市| 澳门| 莆田市| 鹤山市| 蒙自县| 平陆县| 嘉鱼县| 扎囊县| 乐昌市| 精河县| 方山县| 淳安县| 永嘉县| 阜城县| 屯留县| 漳州市| 安吉县| 丹棱县| 桂东县| 金秀| 富源县| 容城县| 拉孜县| 西藏| 华坪县| 嘉善县| 蕉岭县|