【Spring】Spring Async 的实现原理 1 - ProxyProcessorSupport
前言
一般的,在 Spring
框架中,基于 @EnabledAsync
和 @Async
注解的组合,就可以实现对应方法的异步执行(由线程池调度)
本文就是从原理角度简单了解下 Spring Async
的实现原理,主要分几个章节描述如下场景:
ProxyProcessorSupport
类及其两大分支的描述AbstractAdvisingBeanPostProcessor
分支下聚焦于Spring Async
的实现Spring Async
的整体实现流程
可能需要 Spring AOP
相关 API
的铺垫,可以自行了解或查看链接相关文章
ProxyProcessorSupport
ProxyProcessorSupport
是一个ProxyConfig
,它是后处理阶段代理的一个基类- 提供了
evaluateProxyInterfaces
方法,用来推断代理对象的接口,该方法影响最终的代理方式(JDK or CGLIB
) - 该基类的子类有两个核心分支:
AbstractAdvisingBeanPostProcessor
和AbstractAutoProxyCreator
AbstractAutoProxyCreator
ProxyProcessorSupport
的核心分支之一,整个Spring AOP
基于@Aspect
注解切面的实现,就是在该分支下AbstractAutoProxyCreator
是一个SmartInstantiationAwareBeanPostProcessor
,代理 一般 发生在postProcessAfterInitialization
阶段- 它的子类主要是实现方法
getAdvicesAndAdvisorsForBean
,针对对应的bean
实例获取interceptors
用以创建代理对象
AbstractAdvisingBeanPostProcessor
ProxyProcessorSupport
的另一个分支,也是这次文章的主题AbstractAdvisingBeanPostProcessor
是一个BeanPostProcessor
,代理发生在postProcessAfterInitialization
阶段- 与
AbstractAutoProxyCreator
不同的是:这里筛选符合条件的bean
实例进行代理即可,其子类聚焦于指定对应的Advisor
,代码如下:
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (this.advisor == null || bean instanceof AopInfrastructureBean) {
return bean;
}
// ...
// 当前 bean 需要代理
if (isEligible(bean, beanName)) {
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass()) {
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
// 添加对应的 advisor
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != bean.getClass().getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);
}
return bean;
}
--------------- isEligible
protected boolean isEligible(Object bean, String beanName) {
return isEligible(bean.getClass());
}
protected boolean isEligible(Class<?> targetClass) {
// 做了缓存
Boolean eligible = this.eligibleBeans.get(targetClass);
if (eligible != null) {
return eligible;
}
if (this.advisor == null) {
return false;
}
// AopUtils#canApply 方法基于指定 advisor 判断当前类是否需要代理
eligible = AopUtils.canApply(this.advisor, targetClass);
this.eligibleBeans.put(targetClass, eligible);
return eligible;
}
AsyncAnnotationBeanPostProcessor
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
// 指定 advisor 为 AsyncAnnotationAdvisor
AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);
if (this.asyncAnnotationType != null) {
advisor.setAsyncAnnotationType(this.asyncAnnotationType);
}
advisor.setBeanFactory(beanFactory);
this.advisor = advisor;
}
AbstractAdvisingBeanPostProcessor
的子类AsyncAnnotationBeanPostProcessor
,主要是指定具体的advisor
- 在
setBeanFactory
回调中,指定了advisor
为AsyncAnnotationAdvisor
- 因此,该部分
Spring Async
的实现可以总结为:在BeanPostProcessor
的postProcessAfterInitialization
阶段,对满足条件的bean
实例进行代理,具体的代理切点和通知逻辑由AsyncAnnotationAdvisor
决定
总结
本章值得再次一提的就是 ProxyProcessorSupport
的两个分支:
AbstractAutoProxyCreator
:自动代理的基类,基于@Aspect
注解的切面代理就在该分支下实现,其子类主要聚焦于实现获取指定bean
实例对应的interceptors
AbstractAdvisingBeanPostProcessor
:基于Advisor
的代理基类,本章节的主题,其子类主要聚焦于指定具体的Advisor
,比如Spring Async
下的AsyncAnnotationAdvisor
,下一章继续了解