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

歡迎訪問 生活随笔!

生活随笔

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

javascript

Spring AOP 的底层实现

發(fā)布時間:2023/12/20 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring AOP 的底层实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
實例代碼 demo code
  • 創(chuàng)建一個配置類去掃描包,開啟 AspectJ 的自動代理支持
@Configuration @EnableAspectJAutoProxy @ComponentScan("com.aspectj") public class DemoAspectJConfig {// @EnableAspectJAutoProxy 開啟注解 aop 功能// 向 spring 容器中已經(jīng)加入 AnnotationAwareAspectJAutoProxyCreator bean 實例 }
  • 新建接口和接口實現(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 beforeAd(){System.out.println("before-------------");} }
  • 創(chuàng)建啟動類
public class TestAspect {public static void main(String[] args) {// 這一步已經(jīng)生成代理對象,是非懶加載的方式加載// 在容器初始化刷新的時候已經(jīng)向 bean 容器中添加: AnnotationAwareAspectJAutoProxyCreator 對象AnnotationConfigApplicationContext configApplicationContext = new AnnotationConfigApplicationContext(DemoAspectJConfig.class);// 驗證前一步創(chuàng)建的代理對象是否成功DemoDao dao = configApplicationContext.getBean(DemoDao.class);dao.query();} }
  • 啟動 main() 方法,可以看到輸出的內(nèi)容,所有 aop 的功能有啟用
對代碼進行 debug,分析如何創(chuàng)建 bean 對象,并對 bean 對象進行增強
  • 對 main() 方法進行 debug,執(zhí)行完成這一行代碼,已經(jīng)創(chuàng)建出一個被增強的 bean 對象,而不是下面一行才創(chuàng)建增強 bean 對象,這個創(chuàng)建出的 beanName 為 demoDaoImpl

  • 來到 refresh() 方法

  • 來到 refresh() 方法中的 finishBeanFactoryInitialization(beanFactory) 方法,這個方法對 bean 進行實例化和初始化操作

  • 來到 finishBeanFactoryInitialization() 方法中 preInstantiateSingletons() 方法,開始著手實例化 bean 對象

  • 來到 preInstantiateSingletons() 方法,打上斷點,指定 beanName.equals(“demoDaoImpl”),可以看到想要注冊的 bean

  • debug 代碼往下執(zhí)行,來到 getBean(beanName) 方法

  • debug 繼續(xù)往下執(zhí)行,來到 doGetBean(beanName) 方法,在 spring 中一般 do 開頭的方法才是真正做事的方法

  • 最開始創(chuàng)建 bean 對象的時候,通過 getSingleton() 獲取的 sharedInstance 為 null,所有執(zhí)行到 if(sharedInstance != null) 對應(yīng)的 else 邏輯里面

  • 來到 else 邏輯里面的 createBean() 方法,非常核心的方法,debug 進去看

  • 在 createBean() 方法中跳到 doCreateBeanBean 方法中,do 開頭的方法要開始真正創(chuàng)建 bean 對象了

  • doCreateBean() 方法中調(diào)用 addSingletonFactory() 方法,這個邏輯是判斷當前對象是否持有 InstantiationAwareBeanPostProcessor,如果有的話通過它的 getEarlyBeanReference() 方法獲取對象引用,然后將其放到三級緩存中

  • bean 填充 populateBean(),bean 初始化 initializeBean()

    • populateBean() 通過 InstantiationAwareBeanPostProcessor.postProcessProperties() 方法對 bean 屬性進行填充,@Autowired 注入屬性就在這里實現(xiàn)
    • initializeBean() 初始化 bean,通過各種的 BeanPostProcessor 對 bean 進行后置處理
    • 后置處理器的前置處理
    • 后置處理器的后置處理,bean 代理增強就是通過后置處理完成的
    • 可以看到有個后置處理器 AnnotationAwareAspectJAutoProxyCreator,這個處理器就是一個 BeanPostProcessor
    • AbstractAutoProxyCreator 對 postProcessAfterInitialization() 方法進行重寫,wrapIfNecessary() 方法,對 bean 對象進行代理增強
    • 來到 wrapIfNecessary() 方法,查看 bean 有哪些地方需要增強,如果有增強的地方,就對其進行增強,通過 createProxy() 方法,創(chuàng)建代理對象返回
    • 來到 createProxy() 方法,真正創(chuàng)建代理的方法就是 getProxy()
    • getProxy() 執(zhí)行前調(diào)用 createAopProxy() 創(chuàng)建 AopProxyFactory,委托 AopProxyFactory 去創(chuàng)建代理對象
    • 進到 createAopProxy() 方法,先調(diào)用 getAopProxyFactory() 獲取到 AopProxyFactory 對象,再調(diào)用 createAopProxy() 方法
    • createAopProxy() 有個默認的實現(xiàn)類 DefaultAopProxyFactory,該類的默認實現(xiàn),判斷是通過 Jdk 動態(tài)代理 還是 Cglib 代理,到這一步確定返回的代理的類型,確定代理的類型之后,可以根據(jù)返回的對象調(diào)用 getProxy() 方法,生成代理對象
    • Cglib 和 JdkDynamic 通過生成 class 文件對增強的目標進行增強,實現(xiàn)邏輯是 jdk 部分的源碼,之后具體分析,需要留意:
      • JdkDynamic 通過 Proxy 生成的 .class 文件,默認 extends Proxy,所以接口進行代理,要通過 JdkDynamic
      • Cglib 通過對目標類 extends 的方法繼承重寫增強,所以類的增強一定要通過 Cglib 的方式,因為 java 的規(guī)定就是單繼承、多實現(xiàn)

生成字節(jié)碼(.class)文件文件之后如何進行調(diào)用 ?
  • CglibAopProxy
    • 代理對象調(diào)用方法的時候會到 intercept() 方法
    • 拿到所有的 aop advice:List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    • 實例化一個 CglibMethodInvocation(其實就是 ReflectiveMethodInvocation 對象) 對象調(diào)用 proceed() 方法:retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
    • proceed() 方法中遞歸調(diào)用會得到 MethodInterceptor 對象,調(diào)用 invoke() 方法,各種攔截器起作用,進行方法的攔截處理:return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

  • JdkDynamicAopProxy
    • 代理對象調(diào)用方法的時候會到 invoke(),操作和 Cglib 基本一樣
    • 獲取 aop advice:List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    • 實例化 MethodInvocation 對象,調(diào)用 proceed() 方法:MethodInvocation invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
    • 遞歸調(diào)用 Joinpoint.proceed() 方法,同樣也是 ReflectiveMethodInvocation 實現(xiàn)類的 proceed() 方法,各種攔截器起作用,進行方法的攔截處理:return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

  • 上面兩個方法中的 MethodInterceptor.invoke() 方法調(diào)用,其中就包括事物的 TransactionInterceptor,事物的實現(xiàn)就是由該攔截器處理,invoke() 方法調(diào)用 invokeWithinTransaction() 方法真正處理事物
Aop 創(chuàng)建代理對象流程總結(jié)

AbstractApplicationContext.refresh(); 容器刷新
->
AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory); 完成bean工廠的初始化
->
beanFactory.preInstantiateSingletons(); 初始化非懶加載的 bea 實例
->
DefaultListableBeanFactory.getBean(beanName); 創(chuàng)建bean
->
AbstractBeanFactory.getBean(String name); 創(chuàng)建 bean
->
AbstractBeanFactory.doGetBean(String name, @Nullable Class requiredType, @Nullable
Object[] args, boolean typeCheckOnly); 創(chuàng)建 bean
->
createBean(beanName, mbd, args); 創(chuàng)建 bean
->
Object beanInstance = doCreateBean(beanName, mbdToUse, args); 創(chuàng)建 bean
->
exposedObject = initializeBean(beanName, exposedObject, mbd); 初始化 bean
->
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); 獲取所有的 BeanPostProcessor (AnnotationAwareAspectJAutoProxyCreator > AspectJAwareAdvisorAutoProxyCreator > AbstractAdvisorAutoProxyCreator > AbstractAutoProxyCreator 這個類是 BeanPostProcessor 的實現(xiàn)類,是后置處理器實現(xiàn)代理對象增強的關(guān)鍵點)
->
Object current = processor.postProcessAfterInitialization(result, beanName); 調(diào)用所有的 BeanPostProcessor,來到 wrapIfNecessary() 方法
->
AbstractAutoProxyCreator.wrapIfNecessary(bean, beanName, cacheKey); 如果 bean 需要增強,就進行增強
->
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new
SingletonTargetSource(bean)); 創(chuàng)建代理對象
->
proxyFactory.getProxy(getProxyClassLoader()); 獲取代理對象 classLoader
->
createAopProxy().getProxy(classLoader); 判斷代理增強的類型
->
Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this); 生成代理對象

總結(jié)

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

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