【Spring註解】AOP

AOP原理分析就是看給容器中注入了什麼組件,這個組件什麼時候工作,這個組件工作時候的功能

AOP的使用

詳細的AOP功能

實現AOP的詳細步驟

  1. 導入aop模塊

            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-aspects</artifactId>
                <version>5.2.5.RELEASE</version>
            </dependency>
    
  2. 定義一個業務邏輯類(MathCalculator)
    在這裏插入圖片描述

  3. 定義一個日誌切面類

  • 加@Aspect 註解 表明這是一個切面類
  • 在對應的方法上加對應的通知註解
    在這裏插入圖片描述
  1. 配置類
    • 將切面類和業務邏輯類加入到容器中
    • 開啓基於註解的aop模式 @EnableAspectJAutoProxy
      5.

測試:
在這裏插入圖片描述
結果:
在這裏插入圖片描述


@EnableAspectJAutoProxy

@EnableAspectJAutoProxy註解利用AspectJAutoProxyRegistrar給容器中創建了AnnotationAwareAspectJAutoProxyCreator的beandefinition信息,IOC容器在註冊後置處理器的時候就會根據這個beandefinition信息創建AnnotationAwareAspectJAutoProxyCreator的bean 實例

  1. @EnableAspectJAutoProxy
    EnableAspectJAutoProxy上導入了AspectJAutoProxyRegistrar
    在這裏插入圖片描述

AnnotationAwareAspectJAutoProxyCreator的定義信息beandefinition的註冊

  1. AspectJAutoProxyRegistrar
    AspectJAutoProxyRegistrar實現了ImportBeanDefinitionRegistrar, 也就是自定義方式給容器中註冊組件
    AspectJAutoProxyRegistrar 給容器中加入的是beanDefinition ,也就是告訴容器要創建的類型是AnnotationAwareAspectJAutoProxyCreator,名字是
    internalAutoProxyCreator

    在這裏插入圖片描述


    AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); //通過這個方法註冊的bean
    

    這個函數裏具體註冊bean的 是registerOrEscalateApcAsRequired方法

    在這裏插入圖片描述

     registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
    

    通過上面這一句給容器中注入了AnnotationAwareAspectJAutoProxyCreator的定義信息beanDefinition

AnnotationAwareAspectJAutoProxyCreator 的註冊

AnnotationAwareAspectJAutoProxyCreator是 註解模式的AspectJ切面自動代理創建器

父類

通過追溯AnnotationAwareAspectJAutoProxyCreator 的父類 我們可以看到
它其實 實現了兩個接口

  • SmartInstantiationAwareBeanPostProcessor 後置處理器
  • BeanFactoryAware Aware接口的實現類

AnnotationAwareAspectJAutoProxyCreator
-> AspectJAwareAdvisorAutoProxyCreator
-> AbstractAdvisorAutoProxyCreator
->AbstractAutoProxyCreator
->ProxyProcessorSupport
實現SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
在這裏插入圖片描述





其中SmartInstantiationAwareBeanPostProcessor的父類
SmartInstantiationAwareBeanPostProcessor
->InstantiationAwareBeanPostProcessor
->BeanPostProcessor


可以看到就是後置處理器

創建ioc容器

在這裏插入圖片描述
AnnotationConfigApplicationContext:
在這裏插入圖片描述
做了三步


  • 調用無參構造器
  • 註冊配置類
  • 調用refresh() 刷新容器
    refresh() :
    中註冊bean的後置處理器 用來攔截bean的創建
    在這裏插入圖片描述


registerBeanPostProcessors 註冊BeanPostProcessor

registerBeanPostProcessors 方法:
在這裏插入圖片描述

  • 先獲取ioc容器中已經定義了的需要創建對象的所有BeanPostProcessor

    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
    

    現在這些 BeanPostProcessor 都是BeanDefinetion 還沒有創建對象在這裏插入圖片描述

  • 給容器中加入別的BeanPostProcessor

    	beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    
  • 將BeanPostProcessor分類 , 並註冊

    • 實現了PriorityOrdered接口的 priorityOrderedPostProcessors[實現這個接口的有優先級排序]
      在這裏插入圖片描述

    • 實現了Ordered接口的orderedPostProcessors
      在這裏插入圖片描述

    • 沒有實現Oredered接口的nonOrderedPostProcessors
      在這裏插入圖片描述

    • 是MergedBeanDefinitionPostProcessor的 internalPostProcessors
      這個internalPostProcessors 遍歷前面的時候都往這裏加,我還沒搞懂爲這個處理器是個什麼東西在這裏插入圖片描述

      上面的順序就是註冊順序,即優先註冊實現了PriorityOrdered接口的 BeanPostProcessor,再給容器中註冊實現了Ordered接口的BeanPostProcessor,再註冊實現Oredered接口的,最後實現是MergedBeanDefinitionPostProcessor的

    上面這些註冊調用的registerBeanPostProcessors如下:
    拿到所有的後置處理器,調用beanFactory.addBeanPostProcessor ,即把BeanPostProcessor註冊到BeanFactory中
    在這裏插入圖片描述

  • 把容器applicationContext加入

 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));

創建BeanPostProcessor對象

註冊BeanPostProcessor,實際上就是創建BeanPostProcessor對象,保存在容器中

從registerBeanPostProcessors方法中
會調用beanFactory.getBean 來獲取對象(名字爲internalAutoProxyCreator,類型爲後置處理器),那我們第一次是沒有這個對象的 ,所以就會創建一個對象

在這裏插入圖片描述

  • beanFactory.getBean()
    會調用doGetBean

        public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
         
         
           return this.doGetBean(name, requiredType, (Object[])null, false);
       }
    
  • doGetBean
    首先通過getSingleton 獲取 這個單實例對象, 獲取不到,就用 createBean() 創建bean
    在這裏插入圖片描述

    • getSingleton 先去獲取bean
      首先通過getSingleton 用singletonFactory.getObject()獲取bean

      singletonObject = singletonFactory.getObject();
      

      我們第一次訪問 肯定是沒有的, 所以肯定是要去創建
      在這裏插入圖片描述

    • createBean() 創建bean
      通過這一句調用

       return this.createBean(beanName, mbd, args);
      

      參數:
      在這裏插入圖片描述
      調用doCreateBean
      在這裏插入圖片描述


  • doCreateBean

    • 創建bean的實例
      在這裏插入圖片描述

    • 屬性賦值

      this.populateBean(beanName, mbd, instanceWrapper);
      
    • 初始化bean initializeBean

      • invokeAwareMethods
        處理Aware接口的方法回調(利用這些Aware接口對應的方法進行處理)在這裏插入圖片描述

      • applyBeanPostProcessorsBeforeInitialization
        應用後置處理器的postProcessBeforeInitialization方法
        在這裏插入圖片描述

      • invokeInitMethods
        執行自定義的初始化方法

      • applyBeanPostProcessorsAfterInitialization
        執行後置處理器的postProcessAfterInitialization方法
        在這裏插入圖片描述

BeanFactoryAware

通過分析AnnotationAwareAspectJAutoProxyCreator的父類,我們知道它實現了 BeanFactoryAware,所以我們分析它作爲Aware做了哪些工作

實現了BeanFactoryAware的setBeanFactory方法的父類

首先找到所有實現了BeanFactoryAware的setBeanFactory方法的父類:
AbstractAdvisorAutoProxyCreator
AbstractAutoProxyCreator

所以上面創建IOC容器走到了doCreateBean 創建AnnotationAwareAspectJAutoProxyCreator類型的名爲internalAutoProxyCreator 的 bean 時
初始化initializeBean 中 先調用了invokeAwareMethods方法

invokeAwareMethods

由於 實現了BeanFactoryAware,所以這裏時true 就去調用setBeanFactory方法
在這裏插入圖片描述

setBeanFactory

調用的AnnotationAwareAspectJAutoProxyCreator的父類AbstractAdvisorAutoProxyCreator的setBeanFactory方法

在這裏插入圖片描述

  • 父類的setBeanFactory方法
    AbstractAdvisorAutoProxyCreator的父類AbstractAutoProxyCreator也實現了BeanFactoryAware,所以會調用 AbstractAutoProxyCreator的setBeanFactory方法
  • AnnotationAwareAspectJAutoProxyCreator重寫的initBeanFactory方法
    這個方法中調用了initBeanFactory方法,這個方法被AnnotationAwareAspectJAutoProxyCreator重寫了,所以調用的是AnnotationAwareAspectJAutoProxyCreator重寫的initBeanFactory方法
    在這裏插入圖片描述

AnnotationAwareAspectJAutoProxyCreator 作爲後置處理器所做的工作

AnnotationAwareAspectJAutoProxyCreator 是一個後置處理器, 上面我們已經把它放在容器中了,之後任何組件在創建對象的時候 它就可以發揮作用

AnnotationAwareAspectJAutoProxyCreator 的父類AbstractAutoProxyCreator實現的是SmartInstantiationAwareBeanPostProcessor:

public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
   
   

InstantiationAwareBeanPostProcessor 的方法是BeforeInstantiation
在這裏插入圖片描述
這個方法是BeforeInstantiation, 而我們之前接觸的BeanPostProcessor的BeforInitialization方法不一樣
因爲兩種後置處理器類型不一樣


  • BeanPostProcessor
    方法是BeforInitialization
    是在Bean對象創建完成初始化前後調用

  • InstantiationAwareBeanPostProcessor
    方法是BeforeInstantiation
    是在創建Bean實例之前嘗試用後置處理器返回對象的

因此,AnnotationAwareAspectJAutoProxyCreator 會在任何bean創建之前嘗試返回bean的實例

finishBeanFactoryInitialization

首先還是創建ioc容器, 在refresh() 方法中調的是finishBeanFactoryInitialization
在這裏插入圖片描述

finishBeanFactoryInitialization 方法是用來完成beanFactory初始化的,也就是來創建剩下的單實例bean.(因爲之前已經創建了後置處理器之類的bean)

finishBeanFactoryInitialization 方法如下:
調用preInstantiateSingletons 創建剩餘的單實例
在這裏插入圖片描述

  • preInstantiateSingletons
    獲取容器中所有的bean 放到beanNames裏
    在這裏插入圖片描述

然後遍歷beanNames, 通過getBean(beanName)來獲取對象
在這裏插入圖片描述
在這裏插入圖片描述

創建bean

  • getBean
    getBean會調用doGetBean

        public Object getBean(String name) throws BeansException {
         
         
            return this.doGetBean(name, (Class)null, (Object[])null, false);
        }
    
  • doGetBean

    • 先從緩存中獲取當前bean
      在這裏插入圖片描述

    • 緩存中獲取不到再創建
      在這裏插入圖片描述

  • createBean
    在這裏插入圖片描述

    • resolveBeforeInstantiation 解析BeforeInstantiation
      給後置處理器一個機會來返回代理對象,而不是target bean instance.也就是希望後置處理器能在此返回一個代理對象. 如果能返回代理對象就使用,如果不能就調用doCreateBean
      在這裏插入圖片描述

    • doCreateBean

applyBeanPostProcessorsBeforeInstantiation

resolveBeforeInstantiation 中通過applyBeanPostProcessorsBeforeInstantiation方法嘗試返回代理對象

拿到所有的後置處理器,如果這個後置處理器是InstantiationAwareBeanPostProcessor,就調用postProcessBeforeInstantiation方法
在這裏插入圖片描述

postProcessBeforeInstantiation

關心我們的MathCalculator和LogAspect的創建

  • 判斷當前bean是否在advisedBeans中
    advisedBeans中保存了所有需要增強的bean,
  • 判斷當前bean是否是基礎類型isInfrastructureClass
    基礎類型也就是是否實現了Advice\ PointCut\Advisor\AopInfrastructureBean
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章