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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring AOP实现原理解析

發(fā)布時間:2025/3/19 javascript 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring AOP实现原理解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 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接口:
public interface MyService {void test(); }
  • 2.創(chuàng)建ServiceImpl實現(xiàn)類,記得加 @Service 注解,表示由Spring容器管理:
@Service public class MyServiceImpl implements MyService {@Autowiredprivate A a;@Overridepublic void test() {System.out.println("調(diào)用MyService.test");;}@PostConstructpublic void init(){System.out.println("MyServiceImpl PostConstruct");} }
  • 3.創(chuàng)建一個@Component標(biāo)記的常規(guī)類:
@Component public class A {public void test(){System.out.println("a.test...");} }
  • 4.創(chuàng)建啟動類,注意看這時候沒有加注解 @EnableAspectJAutoProxy ,因此Spring不會啟用AOP功能:
@ComponentScan("com.example") public class App {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(App.class);A a = ac.getBean(A.class);a.test();System.out.println(a.getClass());System.out.println("------------------------------------------");MyService service = ac.getBean(MyService.class);service.test();System.out.println(service.getClass());} }
  • 5.執(zhí)行程序,輸出結(jié)果如下。此時,所有的類都是普通的JAVA對象:
MyServiceImpl PostConstruct a.test... class com.example.demo.A ------------------------------------------ 調(diào)用MyService.test class com.example.service.impl.MyServiceImpl
  • 6.接下來,準(zhǔn)備實現(xiàn)AOP了。在前面的基礎(chǔ)上,創(chuàng)建“切面類” TestAspect:
@Component @Aspect public class TestAspect {//這里通過通配符,表示之前的A類和MyServiceImpl類都會被代理。//具體的@Pointcut配置可以查看官網(wǎng)https://docs.spring.io/spring-framework/docs/5.2.13.RELEASE/spring-framework-reference/core.html#spring-core@Pointcut("execution(* com.example.*.*.*(..))")public void myPointCut(){}@Before("myPointCut()")public void before(){System.out.println("before");} }
  • 7.在啟動類增加 @EnableAspectJAutoProxy 注解,然后重新運行程序,新的執(zhí)行結(jié)果如下。此時,A對象變成CGLIB創(chuàng)建的動態(tài)代理對象,而service變成JDK創(chuàng)建的動態(tài)代理對象:
MyServiceImpl PostConstruct before a.test... class com.example.demo.A$$EnhancerBySpringCGLIB$$7c975a0a ------------------------------------------ before 調(diào)用MyService.test class com.sun.proxy.$Proxy23

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)容,希望文章能夠幫你解決所遇到的問題。

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