产生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 是可以交换使用的!
————————————————
版权声明:本文为CSDN博主「老王学源码」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wang489687009/article/details/121628721