1. 程式人生 > 其它 >AOP原始碼解析

AOP原始碼解析

一、AOP整體流程介紹

  

 

 

  1、spring 例項化單例bean,第一次呼叫後置處理器,解析切面@Aspect ,解析切面中的 @Pointcut @befor @after等,生成advisors(說明 一個 @before + 切點 生成一個advisor)

    1.1  org.springframework.context.support.AbstractApplicationContext#refresh() 方法

    1.2 org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization(beanFactory); // 例項化我們剩餘的單例項bean.

    1.3 org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons 

    1.4 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean 建立bean方法

    1.5 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()真正建立bean的方法

      Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 在此處呼叫 第一個後置處理器(InstantiationAwareBeanPostProcessor),解析切面,生成advisors ,進行快取

    1.6 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation 

      InstantiationAwareBeanPostProcessor 後置處理器實現了 BeanpostProcessor ,有2個介面

      方法1:postProcessBeforeInitialization   在bean初始化之前呼叫,用於解析切面,生成advisors

      方法2:postProcessAfterInitialization  bean初始化之後呼叫,用於 生成代理物件

    1.7 org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip 

    1.8 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors

    1.9 org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors  解析切面類,構建advisors,存放到快取中

    2.0 org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisor        -》 new InstantiationModelAwarePointcutAdvisorImp

二、AOP 觸發時機說明

    1、在沒有迴圈依賴的情況下,AOP生成代理 是在 bean的初始化完成以後(屬性賦值之後)

      1.1 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean() 

      1.2 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization 

      1.3 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization 這裡是bean的後置處理器的第九次呼叫,aop和事務都會在這裡生存代理物件

      1.4 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary 

         根據當前bean找到匹配的 (一)中生成的advisor,匹配到了說明需要生成代理物件

      1.5 org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy 建立代理工廠,

        根據 當前bean是否實現介面,,是否設定ProxyTargetClass 屬性 ,判斷生成 jdk的代理工廠,還是cglib的代理工廠

        若我們  ProxyTargetClass 指定為false 且代理類是接口才會走jdk代理 否在我們還是cglib代理  ;;ProxyTargetClass 預設為false;

      1.6 JdkDynamicAopProxy ->Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); 生成代理物件

        CglibAopProxy 生成代理

    2、存在迴圈依賴的情況下,AOP生成代理 是在 bean 例項化以後

三、代理物件呼叫方法,進行增強

  以jdk動態代理為例:

  1. org.springframework.aop.framework.JdkDynamicAopProxy#invoke

    1.1 判斷哪些方法不需要增強  (equals、hashcode 等方法無需增強)

    1.2 獲取到目標物件

    1.3 找到適配到當前目標物件的所有的advisors;如果沒有,,直接執行目標物件方法;如果有 先執行增強方法

    1.4 將目標物件的所有advisors 構造成一個 攔截器鏈一次執行, (說明:此處 使用的是 責任鏈模式) 這裡用了責任鏈的設計模式,遞迴呼叫排序好的攔截器鏈

      執行順序: @AfterTrrowing  @AfterReturning  @After  @Before 

  說明:jdk動態代理 本類方法 A 呼叫 B 不會走動態代理,,可以設定 expose屬性