産生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 的類圖如下:

AbstractAdvisingBeanPostProcessor
某些特别的場景下,Spring 使用了
AbstractAdvisingBeanPostProcessor
來産生 AOP 代理類。
比如:@Async 和 @Validated 的處理
AbstractAdvisingBeanPostProcessor 的原理是:
将指定的 Advisor 用于 bean 的建立。
也就是說,它隻支援指定唯一一個 Advisor 來與 bean 進行比對,比對上就建立 AOP 代理類。
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 代理類的實作有兩種方式:
- 通過 AbstractAdvisorAutoProxyCreator: 從 application context 中擷取所有的 Advisor 用于 AOP 代理類的建立
- 通過 AbstractAdvisingBeanPostProcessor: 指定唯一一個 Advisor 用于 AOP 代理類的建立
不管使用哪種方式,核心都是 Advisor !!!
隻有與 bean 相比對的 Advisor 才能最終應用于 AOP 代理的建立。
AbstractAdvisorAutoProxyCreator 與 AbstractAdvisingBeanPostProcessor 是可以交換使用的!
如果本文對你有所幫助,歡迎點贊收藏!
源碼測試工程下載下傳:
老王讀Spring IoC源碼分析&測試代碼下載下傳
老王讀Spring AOP源碼分析&測試代碼下載下傳
公衆号背景回複:下載下傳IoC 或者 下載下傳AOP 可以免費下載下傳源碼測試工程…
閱讀更多文章,請關注公衆号: 老王學源碼
系列博文:
【老王讀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循環依賴時會報錯?