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

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

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

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

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

環境:Spring5.3.239j428資訊網——每日最新資訊28at.com

本篇文章將介紹兩個主題:9j428資訊網——每日最新資訊28at.com

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

1. 簡介

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

控制流切入

控制流切入允許我們根據方法調用的控制流來定義切入點??刂屏髑腥朦c與當前調用堆棧匹配。例如,如果連接點被com.pack.service包中的方法或PersonService類調用,它可能會觸發??刂屏髑腥朦c是通過使用org.springframework.aop.support.ControlFlowPointcut類指定的。9j428資訊網——每日最新資訊28at.com

引介通知

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

2. 實戰案例

2.1 控制流切入點

準備基礎類

@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算是高級切面類,而這些高級切面類最終會被轉換為Advisor低級切面類。9j428資訊網——每日最新資訊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) ;  }}

測試9j428資訊網——每日最新資訊28at.com

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

控制臺輸出9j428資訊網——每日最新資訊28at.com

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

PersonDAO中的save方法被攔截了。什么意思?怎么PersonDAO就被攔截了,先來看上面切點的定義ControlFlowPointcut9j428資訊網——每日最新資訊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) {    // 取得當前線程的整個執行棧(方法的調用)    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;  }}

通過在這個切點類能知道:9j428資訊網——每日最新資訊28at.com

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

結合上面的測試輸出結果,PersonDAO#save方法被攔截了,因為它符合匹配條件,在PersonService#save方法中調用了PersonDAO#save方法,那PersonDAO#save方法執行棧中就包含了PersonService#save正好匹配了我們定義的切點。9j428資訊網——每日最新資訊28at.com

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

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

2.2 引介通知

引介通知相對比較簡單直接可以在@Aspect切面類中定義9j428資訊網——每日最新資訊28at.com

注備基礎類

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

切面類9j428資訊網——每日最新資訊28at.com

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

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

測試
9j428資訊網——每日最新資訊28at.com

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

控制臺輸出9j428資訊網——每日最新資訊28at.com

計算a + b = 30

UserService能正確的轉換為CommonManager類,這說明UserService生成的代理類實現了CommonManager接口類,同時在執行方法調用的時候使用的是我們制定的默認實現類DefaultCommonManager。9j428資訊網——每日最新資訊28at.com

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

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

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

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

下一篇: 微服務架構下分布式事務處理方案選擇和對比

標簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 来安县| 封开县| 谢通门县| 娱乐| 那坡县| 永城市| 班玛县| 冕宁县| 佛学| 资中县| 方城县| 会同县| 晋城| 铜川市| 山西省| 宝丰县| 贡山| 颍上县| 顺昌县| 文昌市| 日土县| 漯河市| 信丰县| 西盟| 宜川县| 榆中县| 中卫市| 普洱| 鄢陵县| 正镶白旗| 孝义市| 咸宁市| 高密市| 新乡县| 江阴市| 英超| 元阳县| 当涂县| 忻州市| 武隆县| 平顺县|