产生AOP代理类的两种BeanPostProcessor对比: AbstractAdvisorAutoProxyCreator vs 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循环依赖时会报错?