成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

開發(fā) 前端
UserService能正確的轉(zhuǎn)換為CommonManager類,這說明UserService生成的代理類實(shí)現(xiàn)了CommonManager接口類,同時在執(zhí)行方法調(diào)用的時候使用的是我們制定的默認(rèn)實(shí)現(xiàn)類DefaultCommonManager。?

環(huán)境:Spring5.3.23

本篇文章將介紹兩個主題:

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

1. 簡介

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

控制流切入

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

引介通知

引介通知能夠聲明被建議的對象實(shí)現(xiàn)給定的接口,并代表這些對象提供該接口的實(shí)現(xiàn)。簡單說:你有個PersonService類,引介通知能夠讓你不修改代碼的情況下去實(shí)現(xiàn)你給定的任意接口(CommonDAO)。

2. 實(shí)戰(zhàn)案例

2.1 控制流切入點(diǎn)

準(zhǔn)備基礎(chǔ)類

@Component
public class PersonDAO {
  public void save(String name) {
    System.out.println("PersonDAO save method invoke...") ;
  }
}
@Component
public 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低級切面類。

@Component
public 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 ;
  } ;
  // 要進(jìn)行匹配的類
  private static Class<?> clazz = PersonService.class ;
  // 要進(jìn)行匹配的方法(可以為null,這樣指定類中的所有方法都會被匹配攔截)
  private static String methodName = "save" ;
  private static ControlFlowPointcut pointcut = new ControlFlowPointcut(clazz, methodName) ;
  public PackControlFlowAdvisor() {
    super(pointcut, logInterceptor) ;
  }
}

測試

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

控制臺輸出

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

PersonDAO中的save方法被攔截了。什么意思?怎么PersonDAO就被攔截了,先來看上面切點(diǎn)的定義ControlFlowPointcut

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) {
    // 取得當(dāng)前線程的整個執(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;
  }
}

通過在這個切點(diǎn)類能知道:

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

結(jié)合上面的測試輸出結(jié)果,PersonDAO#save方法被攔截了,因為它符合匹配條件,在PersonService#save方法中調(diào)用了PersonDAO#save方法,那PersonDAO#save方法執(zhí)行棧中就包含了PersonService#save正好匹配了我們定義的切點(diǎn)。

簡單說:某個類中的某個方法調(diào)用時會判斷當(dāng)前整個執(zhí)行棧中是否有設(shè)定好的類及方法,如果有則攔截當(dāng)前的方法(執(zhí)行通知)。

注意:控制流切入點(diǎn)比正常切入點(diǎn)慢10-15倍,但在某些情況下它們是有用的。所以大家還是慎重使用吧,畢竟所有的類都被代理了(當(dāng)然這里我們可以自定義matches來控制)。

2.2 引介通知

引介通知相對比較簡單直接可以在@Aspect切面類中定義

注備基礎(chǔ)類

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

切面類

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

注意:在這個切面類中我們并沒有定義@Before,@Around等同志。

測試

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

控制臺輸出

計算a + b = 30

UserService能正確的轉(zhuǎn)換為CommonManager類,這說明UserService生成的代理類實(shí)現(xiàn)了CommonManager接口類,同時在執(zhí)行方法調(diào)用的時候使用的是我們制定的默認(rèn)實(shí)現(xiàn)類DefaultCommonManager。

總結(jié):控制流切入點(diǎn)(ControlFlowPointcut)和引介通知(@DeclareParents)是Spring AOP的兩個重要概念。控制流切入點(diǎn)用于在特定的控制流條件下切入代碼,而引介通知則讓目標(biāo)類具有更加強(qiáng)大的能力。

責(zé)任編輯:武曉燕 來源: Spring全家桶實(shí)戰(zhàn)案例源碼
相關(guān)推薦

2024-07-10 11:26:18

2022-10-31 08:47:21

人臉識別按鍵鍵盤

2024-05-17 09:37:26

format屬性Spring

2020-05-09 16:45:56

ping命令Linux

2024-03-25 08:03:32

技術(shù)面試ShowMeBug協(xié)同編程

2024-10-28 07:10:00

scroll標(biāo)記前端網(wǎng)格布局

2021-03-02 10:50:23

SpringMVC 參數(shù)JavaWeb

2022-08-12 08:25:33

Python異常信息代碼

2020-08-14 08:19:25

Shell命令行數(shù)據(jù)

2017-03-07 09:49:18

存儲

2021-04-01 05:40:53

分庫分表數(shù)據(jù)庫MySQL

2022-01-04 08:00:48

前端技術(shù)Esbuild

2021-02-16 16:43:21

工具性能調(diào)優(yōu)

2019-01-29 10:00:59

GitHub開源搜索

2016-12-02 20:43:28

Android

2017-12-06 15:14:51

AndroidItemRecyclerVie

2020-01-07 10:35:21

QQQQ群手機(jī)QQ

2024-01-18 15:43:37

Linuxaxel工具

2020-10-12 06:28:05

動態(tài)IP框架

2021-01-04 14:16:01

小程序地圖騰訊
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 91色网站 | 狠狠狠 | 日韩中文一区二区 | 久久久视频在线 | 免费看a| 99re视频精品 | 亚洲欧美一区二区三区情侣bbw | 欧美夜夜 | 狠狠狠色丁香婷婷综合久久五月 | 嫩草影院网址 | 色婷婷精品国产一区二区三区 | 中国大陆高清aⅴ毛片 | 国产精品久久国产精品 | 欧美一区二区三区一在线观看 | 国产精品无码久久久久 | 国产在线精品一区二区三区 | 欧洲性生活视频 | 在线成人 | 亚洲一区二区三区在线 | 亚洲免费在线观看av | 亚洲一区中文字幕 | 成人在线视频网 | 国产精品视频免费观看 | 国产成人综合在线 | 操网站| 国产特黄一级 | 一久久久 | 久草网址| www狠狠干 | 欧美一二三 | 国产九九精品 | 伦理午夜电影免费观看 | 欧美日本韩国一区二区三区 | 国内久久 | 艹逼网 | 男人的天堂久久 | 日韩欧美在线视频观看 | 国产中文 | 国产视频黄色 | 久久青青 | 91精品国产一区二区 |