日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring AOP 超详细源码解析

發(fā)布時間:2023/12/20 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring AOP 超详细源码解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

知識章節(jié)

基礎知識

什么是 AOP

  • AOP 的全稱是 “Aspect Oriented Programming”,即面向切面編程
  • 在 AOP 的思想里面,周邊功能(比如性能統(tǒng)計,日志,事務管理等)被定義為切面,核心功能和切面功能分別獨立進行開發(fā),然后把核心功能和切面功能“編織”在一起,這就叫 AOP
  • AOP 能夠?qū)⒛切┡c業(yè)務無關(guān),卻為業(yè)務模塊所共同調(diào)用的邏輯封裝起來,便于減少系統(tǒng)的重復代碼,降低模塊間的耦合度,并有利于未來的可拓展性和可維護性

AOP 基礎概念

  • 連接點(Join point):能夠被攔截的地方,Spring AOP 是基于動態(tài)代理的,所以是方法攔截的,每個成員方法都可以稱之為連接點
  • 切點(Poincut):每個方法都可以稱之為連接點,我們具體定位到某一個方法就成為切點
  • 增強/通知(Advice):表示添加到切點的一段邏輯代碼,并定位連接點的方位信息,簡單來說就定義了是干什么的,具體是在哪干
  • 織入(Weaving):將增強/通知添加到目標類的具體連接點上的過程
  • 引入/引介(Introduction):允許我們向現(xiàn)有的類添加新方法或?qū)傩?#xff0c;是一種特殊的增強
  • 切面(Aspect):切面由切點和增強/通知組成,它既包括了橫切邏輯的定義、也包括了連接點的定義。

  • AOP 五種通知分類
    • 前置通知(Before Advice):在目標方法被調(diào)用前調(diào)用通知功能
    • 后置通知(After Advice):在目標方法被調(diào)用之后調(diào)用通知功能
    • 返回通知(After-returning):在目標方法成功執(zhí)行之后調(diào)用通知功能
    • 異常通知(After-throwing):在目標方法拋出異常之后調(diào)用通知功能
    • 環(huán)繞通知(Around):把整個目標方法包裹起來,在被調(diào)用前和調(diào)用之后分別調(diào)用通知功能

AOP 簡單示例

創(chuàng)建一個配置類,開啟 AspectJ 的自動代理功能

@Configuration @EnableAspectJAutoProxy @ComponentScan("com.aspectj") public class DemoAspectJConfig {// @EnableAspectJAutoProxy 開啟注解 aop 功能// 向 spring 容器中注冊 AnnotationAwareAspectJAutoProxyCreator }

新建接口和接口實現(xiàn)類

// 接口 public interface DemoDao {void query(); }// 實現(xiàn)類 @Component public class DemoDaoImpl implements DemoDao {@Overridepublic void query() {System.out.println("query ......");} }

創(chuàng)建一個切面

@Aspect @Component public class DemoAspect {// 配置切點@Pointcut("execution(* com.aspectj.dao.*.*(..))")public void point(){}// 切點通知@Before("point()")public void beforeAdd(){System.out.println("before-------------");} }

創(chuàng)建啟動類

public class TestAspect {public static void main(String[] args) {// 刷新容器AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(DemoAspectJConfig.class)// 獲取 bean 對象DemoDao dao = configApplicationContext.getBean(DemoDao.class);// 代理對象執(zhí)行dao.query();} }

啟動 main() 方法,可以看到輸出的內(nèi)容,AOP 配置方法執(zhí)行


Spring AOP 執(zhí)行流程


源碼解讀

代碼入口






前置處理

判斷是否是切面








構(gòu)建 bean 對象 advisors 流程
① 遍歷所有的類
② 判斷是否切面,只有切面才會進入后面邏輯
③ 獲取每個 Aspect 的切面列表
④ 保存 Aspect 的切面列表到緩存 advisorsCache<beanName,advisors> 中


獲取切面列表







到這一步,前置處理已經(jīng)完成 !

后置處理

獲取切面






創(chuàng)建代理對象



對象增強處理流程
① 獲取當前 bean 對象 advisors 列表,判斷是否為空
② 不為空就創(chuàng)建代理對象

















切面執(zhí)行



實例化 ReflectiveMethodInvocation 對象,調(diào)用 proceed() 方法


第一次遞歸

數(shù)組的第一個對象是 ExposeInvocationInterceptor,執(zhí)行 invoke(),注意入?yún)⑹?ReflectiveMethodInvocation


第二次遞歸

數(shù)組的第二個對象是 MethodBeforeAdviceInterceptor,執(zhí)行 invoke()




第三次遞歸

如果 advisor 有后置處理,就執(zhí)行第三次遞歸


跳出遞歸


總結(jié)

  • AOP 實現(xiàn)原理
    • 將所有的切面都保存在緩存中
    • 取出緩存中的切面列表,和 bean 對象的所有方法匹配,拿到屬于 bean 對象的切面列表
    • 創(chuàng)建 AOP 代理對象
    • 通過 “責任鏈 + 遞歸”,去執(zhí)行切面邏輯

總結(jié)

以上是生活随笔為你收集整理的Spring AOP 超详细源码解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。