【Spring源码三千问】Spring AOP 中 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 的类图如下:
AbstractAdvisorAutoProxyCreator

AbstractAdvisingBeanPostProcessor

某些特别的场景下,Spring 使用了 AbstractAdvisingBeanPostProcessor 来产生 AOP 代理类。
比如:@Async 和 @Validated 的处理

AbstractAdvisingBeanPostProcessor 的原理是:
将指定的 Advisor 用于 bean 的创建。
也就是说,它只支持指定唯一一个 Advisor 来与 bean 进行匹配,匹配上就创建 AOP 代理类。

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 可以免费下载源码测试工程…

阅读更多文章,请关注公众号: 老王学源码
gzh


系列博文:
【老王读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循环依赖时会报错?

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老王学源码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值