概述
AsyncAnnotationBeanPostProcessor
是一个AbstractBeanFactoryAwareAdvisingPostProcessor/BeanPostProcessor
,它在容器启动时被使用,检测每个bean
是否符合在类级别或者方法级别使用异步注解,如果使用了,则会使用一个AsyncAnnotationAdvisor
包裹该bean
,从而该bean
上通过异步注解所定义的方法在调用时会被真正地异步调用起来。
上面所提到的"异步注解"可以通过AsyncAnnotationBeanPostProcessor
指定,如果不指定,则缺省是指Spring @Async
注解和EJB 3.1 javax.ejb.Asynchronous
注解。
另外在真正执行异步调用的方面,可以为AsyncAnnotationBeanPostProcessor
指定一个任务执行器TaskExecutor
,如果不指定,AsyncAnnotationBeanPostProcessor
会这么决定一个任务执行器:
- 如果容器中存在唯一的一个
TaskExecutor bean
则使用它; - 否则从容器中查找名字为
taskExecutor
类型为Executor
的bean
; - 再不然,就自己创建一个
SimpleAsyncTaskExecutor
使用。
以上该逻辑,可以参考类源代码
AsyncExecutionInterceptor
。
在异步执行的异常处理方面,AsyncAnnotationBeanPostProcessor
也做了考虑。方法调用的异步执行根据返回结果类型分两种情况:
- 返回结果类型为
void
- 返回结果类型为
Future
对于返回结果类型为Future
的情况,不用做任何设置,调用者就可以使用try-catch
机制捕捉异步执行产生的异常。而对于返回结果类型为void
的情况,Spring
支持设置一个AsyncUncaughtExceptionHandler
来支持调用者处理其中发生的异常。这个AsyncUncaughtExceptionHandler
可以通过AsyncAnnotationBeanPostProcessor
来设置。
另外AsyncAnnotationBeanPostProcessor
会将AsyncAnnotationAdvisor
包裹到代理对象的最外面,也就是在调用链中会被优先调用到。
关于AsyncAnnotationBeanPostProcessor
的使用,可以参考如下类 :
- 注解
@EnableAsync
– 导入了AsyncConfigurationSelector
AsyncConfigurationSelector
– 导入了ProxyAsyncConfiguration
ProxyAsyncConfiguration
– 使用AsyncAnnotationBeanPostProcessor
定义基础设施bean asyncAdvisor
源代码
源代码版本 : spring-context-5.1.5.RELEASE
package org.springframework.scheduling.annotation;
import java.lang.annotation.Annotation;
import java.util.concurrent.Executor;
import java.util.function.Supplier;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;