一. 介绍
前面我们在介绍 Spring AOP 的时候生成 proxy 代理对象都是通过 AnnotationAwareAspectJAutoProxyCreator,以及它的抽象父类 AbstractAutoProxyCreator#postProcessAfterInitialization();
AbstractAutoProxyCreator 是一个 BeanPostProcessor,它的 postProcessAfterInitialization() 会找到 bean 容器中匹配的 advisors,如果有对应的 advisors 就会生成 AOP Proxy 代理对象;
但是我们发现 @Async 注解相关的 advisor 在 bean 容器中获取不到!它显然不是通过 AbstractAutoProxyCreator 这个 BeanPostProcessor 生成的 Proxy 代理类对象的;那它是怎么生成 proxy 代理对象的呢?它有 advisor 吗?
先说结论:
- @Async 注解相关的 advisor 不会放到 bean 容器里;
- @Async 注解相关的 advisor 会直接和 AsyncAnnotationBeanPostProcessor 创建绑定,@Async 注解相关的 proxy 是通过 AsyncAnnotationBeanPostProcessor#postProcessAfterInitialization() 生成的;
二. @Async配置
要使用 @Async 注解,需要在配置类上加上 @EnableAsync,因为 @EnableAsync 才会往容器中注入我们需要的 AsyncAnnotationBeanPostProcessor;
我们简单看下 @EnableAsync 开启的配置类;
// ------------------------------- AsyncConfigurationSelector -------------------------------
public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";
/**
*/
@Override
@NonNull
public String[] selectImports(AdviceMode adviceMode) {
return switch (adviceMode) {
// 默认往容器中注入 ProxyAsyncConfiguration 配置类,它是 JDK 代理相关的配置类
// 如果是 Aspectj,导入的是 AspectJAsyncConfiguration 配置类
case PROXY -> new String[] {ProxyAsyncConfiguration.class.getName()};
case ASPECTJ -> new String[] {ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME};
};
}
}
// --------------------------------- ProxyAsyncConfiguration ---------------------------------
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
@Bean(name = TaskManagementConfigUtils.ASYNC_ANNOTATION_PROCESSOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public AsyncAnnotationBeanPostProcessor asyncAdvisor() {
// 1. 创建出 AsyncAnnotationBeanPostProcessor 并放到 bean 容器中
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
// 2. 配置 @Async 相关的线程池 executor、错误处理器 exceptionHandler
bpp.configure(this.executor, this.exceptionHandler);
Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
// 3. 设置 order,了解即可
// @EnableAsync 默认的 order 是最小的,order = Ordered.LOWEST_PRECEDENCE
// 之所以设置最小,是为了让 AsyncAnnotationBeanPostProcessor 在最后执行
// 目的是让其他 BeanPostProcessor 执行完后,以便往现有代理中添加 advisor
bpp.setOrder(this.enableAsync.<Integer>getNumber("order"));
return bpp;
}
}
我们来先看一下 AsyncAnnotationBeanPostProcessor 的类图,可以看到它是 BeanPostProssor 的实现类;
// -------------------------------- AsyncAnnotationBeanPostProcessor ------------------------------
public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor {
public static final String DEFAULT_TASK_EXECUTOR_BEAN_NAME =
AnnotationAsyncExecutionInterceptor.DEFAULT_TASK_EXECUTOR_BEAN_NAME;
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private Supplier<Executor> executor;
@Nullable
private Supplier<AsyncUncaughtExceptionHandler> exceptionHandler;
@Nullable
private Class<? extends Annotation> asyncAnnotationType;
public AsyncAnnotationBeanPostProcessor() {
setBeforeExistingAdvisors(true);
}
public void configure(
@Nullable Supplier<Executor> executor,
@Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
this.executor = executor;
this.exceptionHandler = exceptionHandler;
}
public void setExecutor(Executor executor) {
this.executor = SingletonSupplier.of(executor);
}
public void setExceptionHandler(AsyncUncaughtExceptionHandler exceptionHandler) {
this.exceptionHandler = SingletonSupplier.of(exceptionHandler);
}
public void setAsyncAnnotationType(Class<? extends Annotation> asyncAnnotationType) {
Assert.notNull(asyncAnnotationType, "'asyncAnnotationType' must not be null");
this.asyncAnnotationType = asyncAnnotationType;
}
/**
* BeanFactoryAware 的接口,Spring Bean 容器初始化后会执行该后处理器
*
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
// 创建了一个 AsyncAnnotationAdvisor
// 可以看到 @Async 相关的 advisor 不会放到 bean 容器中!
// 而是直接和 AsyncAnnotationBeanPostProcessor 关联,且只有这一个 advisor
// AsyncAnnotationAdvisor 的 pointcut 其实就是匹配类/方法上的 @Async 注解
AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor,
this.exceptionHandler);
if (this.asyncAnnotationType != null) {
advisor.setAsyncAnnotationType(this.asyncAnnotationType);
}
advisor.setBeanFactory(beanFactory);
this.advisor = advisor;
}
}
下面我们看下 AsyncAnnotationBeanPostProcessor 的 postProcessAfterInitialization() 做了啥;
三. AsyncAnnotationBeanPostProcessor
我们看下 AsyncAnnotationBeanPostProcessor 的 postProcessAfterInitialization();
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 1. advsior 是 AsyncAnnotationAdvisor,一般不会走进这个判断
if (this.advisor == null || bean instanceof AopInfrastructureBean) {
return bean;
}
// 2. 如果 bean 是 Advised 接口,表示 bean 已经是 Spring AOP 代理类对象
// 这个我们在前面讲过,不记得的话可以看前面的章节
if (bean instanceof Advised advised) {
// 如果当前代理允许继续添加 advice 并且 当前 bean 需要代理的话
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
// 默认就是 this.beforeExistingAdvisors == true
// 表示将当前 AsyncAnnotationAdvisor 放在 advisor 的最前面,优先匹配 AsyncAnnotationAdvisor
// 我们在上面讲过 AsyncAnnotationBeanPostProcessor 的 order 默认是最小的
// 就是为了让所有的 advisors 加载完毕,好让 AsyncAnnotationAdvisor 放在第一位优先匹配!
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
}
else if (advised.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE &&
advised.getAdvisorCount() > 0) {
advised.addAdvisor(advised.getAdvisorCount() - 1, this.advisor);
return bean;
}
else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
// 3. 当前 bean 不是 Advised 接口,表示 bean 还未被代理过,不是 Spring AOP 代理对象
// 如果当前 bean 匹配 advisor 的话
// 由我们去创建 ProxyFactory,放入 asyncAnnotationAdvisor,创建出 Proxy 代理类对象
if (isEligible(bean, beanName)) {
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass()) {
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader smartClassLoader &&
classLoader != bean.getClass().getClassLoader()) {
classLoader = smartClassLoader.getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);
}
// 4. 不匹配当前 asyncAnnotationAdvisor,不进行代理,返回原始 bean 对象
return bean;
}
至此,@Async 相关的 AsyncAnnotationAdvisor 就加入到了 ProxyFactory 的 advisors 里了,且生成了 Spring AOP 代理类对象;
下面我们看下 AsyncAnnotationAdvisor 中的 advice 是哪个?这个 Advice 的 invoke() 会对方法做哪些拦截改造呢?
四. AsyncAnnotationAdvisor
AsyncAnnotationAdvisor 类如下:
public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
// 对应的 advice
private final Advice advice;
// 对应的 pointcut
private Pointcut pointcut;
public AsyncAnnotationAdvisor() {
this((Supplier<Executor>) null, (Supplier<AsyncUncaughtExceptionHandler>) null);
}
public AsyncAnnotationAdvisor(
@Nullable Executor executor, @Nullable AsyncUncaughtExceptionHandler exceptionHandler) {
this(SingletonSupplier.ofNullable(executor), SingletonSupplier.ofNullable(exceptionHandler));
}
@SuppressWarnings("unchecked")
public AsyncAnnotationAdvisor(
@Nullable Supplier<Executor> executor,
@Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<>(2);
asyncAnnotationTypes.add(Async.class);
ClassLoader classLoader = AsyncAnnotationAdvisor.class.getClassLoader();
asyncAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("jakarta.ejb.Asynchronous", classLoader));
asyncAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("jakarta.enterprise.concurrent.Asynchronous", classLoader));
// 根据给定的 executor、exceptionHandler 创建出 Advice
// 这个 Advice 根据下面可以看出是 AnnotationAsyncExecutionInterceptor
this.advice = buildAdvice(executor, exceptionHandler);
this.pointcut = buildPointcut(asyncAnnotationTypes);
}
protected Advice buildAdvice(
@Nullable Supplier<Executor> executor,
@Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
// Advice 为 AnnotationAsyncExecutionInterceptor
AnnotationAsyncExecutionInterceptor interceptor =
new AnnotationAsyncExecutionInterceptor(null);
interceptor.configure(executor, exceptionHandler);
return interceptor;
}
protected Pointcut buildPointcut(Set<Class<? extends Annotation>> asyncAnnotationTypes) {
ComposablePointcut result = null;
for (Class<? extends Annotation> asyncAnnotationType : asyncAnnotationTypes) {
// class pointcut:匹配类上的 @Async 注解
Pointcut cpc = new AnnotationMatchingPointcut(asyncAnnotationType, true);
// method pointcut:匹配 method 上的 @Async 注解
Pointcut mpc = new AnnotationMatchingPointcut(null, asyncAnnotationType, true);
if (result == null) {
result = new ComposablePointcut(cpc);
}
else {
result.union(cpc);
}
result = result.union(mpc);
}
return (result != null ? result : Pointcut.TRUE);
}
}
Advice 是 AnnotationAsyncExecutionInterceptor,我们看下 AnnotationAsyncExecutionInterceptor#invoke();它的 invoke() 在它的父类 AsyncExecutionInterceptor 上;
1. AnnotationAsyncExecutionInterceptor
AsyncExecutionInterceptor#invoke() 如下:
// ------------------------------- AsyncExecutionInterceptor ------------------------------
public Object invoke(final MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ?
AopUtils.getTargetClass(invocation.getThis()) : null);
Method userMethod = BridgeMethodResolver.getMostSpecificMethod(invocation.getMethod(),
targetClass);
// 1. 选择指定的线程池 asyncTaskExecutor
AsyncTaskExecutor executor = determineAsyncExecutor(userMethod);
// 2. 将目标方法的执行封装为一个 Callable 对象
Callable<Object> task = () -> {
try {
Object result = invocation.proceed();
if (result instanceof Future<?> future) {
// 对于 @Async 注解的方法
// 如果方法需要返回值,需要包装成 Future 类对象
// 一般是 AsyncResult,如 return new AsyncResult<>("ok")
return future.get();
}
}
catch (ExecutionException ex) {
handleError(ex.getCause(), userMethod, invocation.getArguments());
}
catch (Throwable ex) {
// 3. 如果有异常的话,进行异常处理
handleError(ex, userMethod, invocation.getArguments());
}
return null;
};
// 4. 执行 doSubmit()
// 将封装好的 task 提交到线程池 asyncTaskExecutor 中执行
return doSubmit(task, executor, invocation.getMethod().getReturnType());
}
// ------------------------------- AsyncExecutionInterceptor ------------------------------
protected Object doSubmit(Callable<Object> task, AsyncTaskExecutor executor, Class<?> returnType) {
// 1. 方法返回值是 ListenableFuture、Future 之类时,会返回 Future 类对象
if (CompletableFuture.class.isAssignableFrom(returnType)) {
return executor.submitCompletable(task);
}
else if (ListenableFuture.class.isAssignableFrom(returnType)) {
return ((org.springframework.core.task.AsyncListenableTaskExecutor)executor)
.submitListenable(task);
}
else if (Future.class.isAssignableFrom(returnType)) {
return executor.submit(task);
}
// 2. 方法返回值是 void,返回 null
else if (void.class == returnType) {
executor.submit(task);
return null;
}
// 3. 方法返回值只能是 Future、void,其他类型会抛异常
else {
throw new IllegalArgumentException(
"Invalid return type for async method (only Future and void supported): " + returnType);
}
}
至此,AsyncExecutionInterceptor#invoke() 结束;