天天看點

【Spring源碼三千問】Spring AOP 中 AbstractAdvisorAutoProxyCreator、AbstractAdvisingBeanPostProcessor的差別前言版本約定正文小結

産生AOP代理類的兩種BeanPostProcessor對比: AbstractAdvisorAutoProxyCreator vs AbstractAdvisingBeanPostProcessor

  • 前言
  • 版本約定
  • 正文
    • AutoProxyCreator: AbstractAdvisorAutoProxyCreator
    • AbstractAdvisingBeanPostProcessor
    • AbstractAdvisorAutoProxyCreator 與 AbstractAdvisingBeanPostProcessor 對比
    • AbstractAdvisorAutoProxyCreator 與 AbstractAdvisingBeanPostProcessor 是可以互相交換使用的
  • 小結

前言

在分析 @Aspect 和 @Transactional 的實作時,我們發現,Spring AOP 代理類都是通過 AutoProxyCreator(通常是: AnnotationAwareAspectJAutoProxyCreator)來産生的。

而在分析 @Async 時,則發現,Spring AOP 代理類是通過 AsyncAnnotationBeanPostProcessor 來生成的。

這兩種方式有什麼相同點和不同點呢?下面我們就來分析一下

版本約定

Spring 5.3.9 (通過 SpringBoot 2.5.3 間接引入的依賴)

正文

AutoProxyCreator: AbstractAdvisorAutoProxyCreator

絕大部分的場景下,Spring AOP 代理對象都是通過 AutoProxyCreator 來産生的。

它的原理是:

擷取 application context 中所有的 Advisor,然後選擇與 bean 相比對的 Advisor 來生成 AOP 代理類

AbstractAdvisorAutoProxyCreator 的類圖如下:

【Spring源碼三千問】Spring AOP 中 AbstractAdvisorAutoProxyCreator、AbstractAdvisingBeanPostProcessor的差別前言版本約定正文小結

AbstractAdvisingBeanPostProcessor

某些特别的場景下,Spring 使用了

AbstractAdvisingBeanPostProcessor

來産生 AOP 代理類。

比如:@Async 和 @Validated 的處理

AbstractAdvisingBeanPostProcessor 的原理是:

将指定的 Advisor 用于 bean 的建立。

也就是說,它隻支援指定唯一一個 Advisor 來與 bean 進行比對,比對上就建立 AOP 代理類。

【Spring源碼三千問】Spring AOP 中 AbstractAdvisorAutoProxyCreator、AbstractAdvisingBeanPostProcessor的差別前言版本約定正文小結

AbstractAdvisorAutoProxyCreator 與 AbstractAdvisingBeanPostProcessor 對比

相同點:

兩者都是 BeanPostProcessor,都會在 postProcessAfterInitialization() 時,将 Advisor 應用到 AOP 代理 bean 的建立中。

不同點:

  • AbstractAdvisorAutoProxyCreator:

    它不會指定 Advisor,而是通過 getAdvicesAndAdvisorsForBean() 來擷取 Advisor 的,擷取與 bean 比對的 Advisor 可以是多個,擷取的途徑可以是從 application context 中擷取。

    典型的實作類: AnnotationAwareAspectJAutoProxyCreator

  • AbstractAdvisingBeanPostProcessor:

    它指定了一個 Advisor 用于 AOP 代理的建立。Advisor 與 bean 比對上才會建立 AOP 代理類。

    典型的實作類: AsyncAnnotationBeanPostProcessor、MethodValidationPostProcessor

AbstractAdvisorAutoProxyCreator 與 AbstractAdvisingBeanPostProcessor 是可以互相交換使用的

比如 @Transactional 的場景,我們即可以定義一個 Advisor bean: BeanFactoryTransactionAttributeSourceAdvisor,也可以實作一個自定義的 AbstractAdvisingBeanPostProcessor 來指定這個 Advisor 的方式來實作。

再比如 @Validated 的場景,Spring 源碼中是使用 MethodValidationPostProcessor 來實作的(實作 AbstractAdvisingBeanPostProcessor 的方式),同樣,我們也可以通過定義一個 Advisor bean 的方式來實作。

光說不練假把式,我們直接上代碼:

@Configuration
public class ValidationConfig {
    // 直接定義一個 Advisor bean,讓 AutoProxyCreator 來使用 Advisor 來産生代理 bean  
    @Bean
    public Advisor validAdvisor(){
        Pointcut pointcut = new AnnotationMatchingPointcut(Validated.class, true);
        return new DefaultPointcutAdvisor(pointcut, new MethodValidationInterceptor());
    }
}

// 排除掉 Validation 的自動配置,使用自定義的配置: ValidationConfig
@SpringBootApplication(exclude = ValidationAutoConfiguration.class)
@EnableAspectJAutoProxy
public class Validated2Application {

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(Validated2Application.class);
        app.setBannerMode(Banner.Mode.OFF);
        app.run(args);
    }
}
           

我們通過在啟動類中排隊掉 SpringBoot 自動配置的 ValidationAutoConfiguration,然後添加自己定義的 Advisor bean : validAdvisor,同樣也實作了參數校驗的功能。

小結

Spring AOP 中産生代理類的底層原理都是通過 Advisor 與 bean 進行比對,比對上的 Advisor 就會用于 AOP 代理類的建立。

産生 Spring AOP 代理類的實作有兩種方式:

  1. 通過 AbstractAdvisorAutoProxyCreator: 從 application context 中擷取所有的 Advisor 用于 AOP 代理類的建立
  2. 通過 AbstractAdvisingBeanPostProcessor: 指定唯一一個 Advisor 用于 AOP 代理類的建立

不管使用哪種方式,核心都是 Advisor !!!

隻有與 bean 相比對的 Advisor 才能最終應用于 AOP 代理的建立。

AbstractAdvisorAutoProxyCreator 與 AbstractAdvisingBeanPostProcessor 是可以交換使用的!

如果本文對你有所幫助,歡迎點贊收藏!

源碼測試工程下載下傳:

老王讀Spring IoC源碼分析&測試代碼下載下傳

老王讀Spring AOP源碼分析&測試代碼下載下傳

公衆号背景回複:下載下傳IoC 或者 下載下傳AOP 可以免費下載下傳源碼測試工程…

閱讀更多文章,請關注公衆号: 老王學源碼

【Spring源碼三千問】Spring AOP 中 AbstractAdvisorAutoProxyCreator、AbstractAdvisingBeanPostProcessor的差別前言版本約定正文小結

系列博文:

【老王讀Spring AOP-0】SpringAop引入&&AOP概念、術語介紹

【老王讀Spring AOP-1】Pointcut如何比對到 join point

【老王讀Spring AOP-2】如何為 Pointcut 比對的類生成動态代理類

【老王讀Spring AOP-3】Spring AOP 執行 Pointcut 對應的 Advice 的過程

【老王讀Spring AOP-4】Spring AOP 與Spring IoC 結合的過程 && ProxyFactory 解析

【老王讀Spring AOP-5】@Transactional産生AOP代理的原理

【老王讀Spring AOP-6】@Async産生AOP代理的原理

【Spring 源碼閱讀】Spring IoC、AOP 原理小總結

相關閱讀:

【Spring源碼三千問】Spring動态代理:什麼時候使用的 cglib,什麼時候使用的是 jdk proxy?

【Spring源碼三千問】Advice、Advisor、Advised都是什麼接口?

【Spring源碼三千問】沒有AspectJ,Spring中如何使用SpringAOP、@Transactional?

【Spring源碼三千問】Spring AOP 中 AbstractAdvisorAutoProxyCreator、AbstractAdvisingBeanPostProcessor的差別

【Spring 源碼三千問】同樣是AOP代理bean,為什麼@Async标記的bean循環依賴時會報錯?