javascript
Spring AOP实现原理解析
文章目錄
- 1. 前言
- 2. 代理示例
- 3. 問題分析
- 4. 結(jié)尾
1. 前言
AOP,英文全稱是Aspect Oriented Programming,也叫作面向切面編程。預(yù)先定義一個或多個切入點,當(dāng)程序執(zhí)行到切點的方法時,會先執(zhí)行切面相關(guān)處理邏輯,再執(zhí)行原程序代碼。
注:本篇文章會結(jié)合Spring生命周期源碼,介紹AOP是如何整合到Sping容器管理。不會過多地介紹一些基礎(chǔ)知識,閱讀之前,最好對AOP、CGLIB、Proxy有個基礎(chǔ)的了解。
Spring通過動態(tài)代理實現(xiàn)AOP,用語言表述可能不大清楚,下面畫一張圖來對比一下
2. 代理示例
- 1.創(chuàng)建Service接口:
- 2.創(chuàng)建ServiceImpl實現(xiàn)類,記得加 @Service 注解,表示由Spring容器管理:
- 3.創(chuàng)建一個@Component標(biāo)記的常規(guī)類:
- 4.創(chuàng)建啟動類,注意看這時候沒有加注解 @EnableAspectJAutoProxy ,因此Spring不會啟用AOP功能:
- 5.執(zhí)行程序,輸出結(jié)果如下。此時,所有的類都是普通的JAVA對象:
- 6.接下來,準(zhǔn)備實現(xiàn)AOP了。在前面的基礎(chǔ)上,創(chuàng)建“切面類” TestAspect:
- 7.在啟動類增加 @EnableAspectJAutoProxy 注解,然后重新運行程序,新的執(zhí)行結(jié)果如下。此時,A對象變成CGLIB創(chuàng)建的動態(tài)代理對象,而service變成JDK創(chuàng)建的動態(tài)代理對象:
3. 問題分析
問題1:Spring在什么時機(jī)點進(jìn)行AOP處理?
答案1:
- 在創(chuàng)建Bean對象之后,調(diào)用后置處理器方法AnnotationAwareAspectJAutoProxyCreator#postProcessAfterInitialization()創(chuàng)建動態(tài)代理實現(xiàn)
看下面這張圖,描述了Bean創(chuàng)建的過程和AOP的調(diào)用時機(jī)
問題2:上一步提的處理器AnnotationAwareAspectJAutoProxyCreator沒有加@Component注解,為什么能被Spring掃描到并起作用?
答案2:----------------------------------------------------------------------------------------
-
Spring AOP生效必須加注解@EnableAspectJAutoProxy,該注解使用@Import將AspectJAutoProxyRegistrar加入了Spring容器
-
AspectJAutoProxyRegistrar是實現(xiàn)ImportBeanDefinitionRegistrar接口的處理器,在Spring掃描類的過程中,會調(diào)用所有實現(xiàn)類的 registerBeanDefinitions 方法
-
AspectJAutoProxyRegistrar#registerBeanDefinitions() 將 AnnotationAwareAspectJAutoProxyCreator 加入了 Spring 容器
問題3:Spring采用哪種動態(tài)代理機(jī)制,CGLIB還是JDK?
答案3:----------------------------------------------------------------------------------------
- 默認(rèn)情況下,實現(xiàn)了業(yè)務(wù)接口的Bean會采用JDK動態(tài)代理,例如:ServiceImpl。其他情況下,一般會采用CGLIB動態(tài)代理。
- 設(shè)置注解 @EnableAspectJAutoProxy 的屬性 proxyTargetClass = true,會強(qiáng)制 CGLIB 動態(tài)代理
修改之前的例子,使用注解 @EnableAspectJAutoProxy(proxyTargetClass = true) ,重新運行程序,執(zhí)行結(jié)果如下:
MyServiceImpl PostConstruct before a.test... class com.example.demo.A$$EnhancerBySpringCGLIB$$7c975a0a ------------------------------------------ before 調(diào)用MyService.test class com.example.service.impl.MyServiceImpl$$EnhancerBySpringCGLIB$$98d88524看吧… 全部變成CGLIB創(chuàng)建的代理對象
4. 結(jié)尾
本篇的AOP基本原理就介紹到這里了,后面有新的想法會不斷補(bǔ)充,也歡迎大家提出新的見解。
總結(jié)
以上是生活随笔為你收集整理的Spring AOP实现原理解析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring扫描类过程解析和案例
- 下一篇: asn1 pem pfx格式证书_Spr