當(dāng)前位置:
首頁(yè) >
前端技术
> javascript
>内容正文
javascript
Spring AOP 超详细源码解析
生活随笔
收集整理的這篇文章主要介紹了
Spring AOP 超详细源码解析
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
知識(shí)章節(jié)
基礎(chǔ)知識(shí)
什么是 AOP
- AOP 的全稱(chēng)是 “Aspect Oriented Programming”,即面向切面編程
- 在 AOP 的思想里面,周邊功能(比如性能統(tǒng)計(jì),日志,事務(wù)管理等)被定義為切面,核心功能和切面功能分別獨(dú)立進(jìn)行開(kāi)發(fā),然后把核心功能和切面功能“編織”在一起,這就叫 AOP
- AOP 能夠?qū)⒛切┡c業(yè)務(wù)無(wú)關(guān),卻為業(yè)務(wù)模塊所共同調(diào)用的邏輯封裝起來(lái),便于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度,并有利于未來(lái)的可拓展性和可維護(hù)性
AOP 基礎(chǔ)概念
- 連接點(diǎn)(Join point):能夠被攔截的地方,Spring AOP 是基于動(dòng)態(tài)代理的,所以是方法攔截的,每個(gè)成員方法都可以稱(chēng)之為連接點(diǎn)
- 切點(diǎn)(Poincut):每個(gè)方法都可以稱(chēng)之為連接點(diǎn),我們具體定位到某一個(gè)方法就成為切點(diǎn)
- 增強(qiáng)/通知(Advice):表示添加到切點(diǎn)的一段邏輯代碼,并定位連接點(diǎn)的方位信息,簡(jiǎn)單來(lái)說(shuō)就定義了是干什么的,具體是在哪干
- 織入(Weaving):將增強(qiáng)/通知添加到目標(biāo)類(lèi)的具體連接點(diǎn)上的過(guò)程
- 引入/引介(Introduction):允許我們向現(xiàn)有的類(lèi)添加新方法或?qū)傩?#xff0c;是一種特殊的增強(qiáng)
- 切面(Aspect):切面由切點(diǎn)和增強(qiáng)/通知組成,它既包括了橫切邏輯的定義、也包括了連接點(diǎn)的定義。
- AOP 五種通知分類(lèi)
- 前置通知(Before Advice):在目標(biāo)方法被調(diào)用前調(diào)用通知功能
- 后置通知(After Advice):在目標(biāo)方法被調(diào)用之后調(diào)用通知功能
- 返回通知(After-returning):在目標(biāo)方法成功執(zhí)行之后調(diào)用通知功能
- 異常通知(After-throwing):在目標(biāo)方法拋出異常之后調(diào)用通知功能
- 環(huán)繞通知(Around):把整個(gè)目標(biāo)方法包裹起來(lái),在被調(diào)用前和調(diào)用之后分別調(diào)用通知功能
AOP 簡(jiǎn)單示例
創(chuàng)建一個(gè)配置類(lèi),開(kāi)啟 AspectJ 的自動(dòng)代理功能
@Configuration @EnableAspectJAutoProxy @ComponentScan("com.aspectj") public class DemoAspectJConfig {// @EnableAspectJAutoProxy 開(kāi)啟注解 aop 功能// 向 spring 容器中注冊(cè) AnnotationAwareAspectJAutoProxyCreator }新建接口和接口實(shí)現(xiàn)類(lèi)
// 接口 public interface DemoDao {void query(); }// 實(shí)現(xiàn)類(lèi) @Component public class DemoDaoImpl implements DemoDao {@Overridepublic void query() {System.out.println("query ......");} }創(chuàng)建一個(gè)切面
@Aspect @Component public class DemoAspect {// 配置切點(diǎn)@Pointcut("execution(* com.aspectj.dao.*.*(..))")public void point(){}// 切點(diǎn)通知@Before("point()")public void beforeAdd(){System.out.println("before-------------");} }創(chuàng)建啟動(dòng)類(lèi)
public class TestAspect {public static void main(String[] args) {// 刷新容器AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(DemoAspectJConfig.class)// 獲取 bean 對(duì)象DemoDao dao = configApplicationContext.getBean(DemoDao.class);// 代理對(duì)象執(zhí)行dao.query();} }啟動(dòng) main() 方法,可以看到輸出的內(nèi)容,AOP 配置方法執(zhí)行
Spring AOP 執(zhí)行流程
源碼解讀
代碼入口
前置處理
判斷是否是切面
構(gòu)建 bean 對(duì)象 advisors 流程
① 遍歷所有的類(lèi)
② 判斷是否切面,只有切面才會(huì)進(jìn)入后面邏輯
③ 獲取每個(gè) Aspect 的切面列表
④ 保存 Aspect 的切面列表到緩存 advisorsCache<beanName,advisors> 中
獲取切面列表
到這一步,前置處理已經(jīng)完成 !
后置處理
獲取切面
創(chuàng)建代理對(duì)象
對(duì)象增強(qiáng)處理流程
① 獲取當(dāng)前 bean 對(duì)象 advisors 列表,判斷是否為空
② 不為空就創(chuàng)建代理對(duì)象
切面執(zhí)行
實(shí)例化 ReflectiveMethodInvocation 對(duì)象,調(diào)用 proceed() 方法
第一次遞歸
數(shù)組的第一個(gè)對(duì)象是 ExposeInvocationInterceptor,執(zhí)行 invoke(),注意入?yún)⑹?ReflectiveMethodInvocation
第二次遞歸
數(shù)組的第二個(gè)對(duì)象是 MethodBeforeAdviceInterceptor,執(zhí)行 invoke()
第三次遞歸
如果 advisor 有后置處理,就執(zhí)行第三次遞歸
跳出遞歸
總結(jié)
- AOP 實(shí)現(xiàn)原理
- 將所有的切面都保存在緩存中
- 取出緩存中的切面列表,和 bean 對(duì)象的所有方法匹配,拿到屬于 bean 對(duì)象的切面列表
- 創(chuàng)建 AOP 代理對(duì)象
- 通過(guò) “責(zé)任鏈 + 遞歸”,去執(zhí)行切面邏輯
總結(jié)
以上是生活随笔為你收集整理的Spring AOP 超详细源码解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《和平精英》与永久自行车界合作
- 下一篇: JS清除网页历史记录,屏蔽后退按钮