前言@EnableAsyncAsyncConfigurationSelectorProxyAsyncConfiguration
AbstractAsyncConfigurationProxyAsyncConfiguration 总结
前言本章节从引入 Spring Async 的 @EnableAsync 注解入手,了解下整个引入流程
@EnableAsync@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@documented
@import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
// spring async 的注解类型
Class extends Annotation> annotation() default Annotation.class;
// 影响代理方式(JDK or CGLIB)
boolean proxyTargetClass() default false;
// 基于 代理 或 AspectJ 的通知模式,默认就是前者
AdviceMode mode() default AdviceMode.PROXY;
// 排序值
int order() default Ordered.LOWEST_PRECEDENCE;
}
一些通知相关的核心属性重点是 import 了配置类 AsyncConfigurationSelector,会引入一些必要的 bean 组件 AsyncConfigurationSelector
public class AsyncConfigurationSelector extends AdviceModeimportSelector{ // ... @Override @Nullable public String[] selectimports(AdviceMode adviceMode) { // 该属性从注解元数据获取 switch (adviceMode) { case PROXY: return new String[] {ProxyAsyncConfiguration.class.getName()}; case ASPECTJ: return new String[] {ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME}; default: return null; } } }
AsyncConfigurationSelector 是一个 importSelector(可见父类 AdviceModeimportSelector),其 selectimports 方法会返回对应的 bean 组件类名,最终被注册进容器通常情况下,注册的配置类为 ProxyAsyncConfiguration ProxyAsyncConfiguration AbstractAsyncConfiguration
@Configuration(proxyBeanMethods = false)
public abstract class AbstractAsyncConfiguration implements importAware {
// ...
// 获取容器中的 AsyncConfigurer
@Autowired
void setConfigurers(ObjectProvider configurers) {
Supplier configurer = SingletonSupplier.of(() -> {
List candidates = configurers.stream().collect(Collectors.toList());
if (CollectionUtils.isEmpty(candidates)) {
return null;
}
if (candidates.size() > 1) {
throw new IllegalStateException("only one AsyncConfigurer may exist");
}
return candidates.get(0);
});
// 如果有且仅有一个 AsyncConfigurer 实例,则从中解析 executor 和 exceptionHandler
this.executor = adapt(configurer, AsyncConfigurer::getAsyncExecutor);
this.exceptionHandler = adapt(configurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler);
}
// ...
}
父类 AbstractAsyncConfiguration 是 Spring Async 配置基类,此处允许用户提供一个唯一的 AsyncConfigurer 配置类,从中获取对应的 executor 和 exceptionHandler如果不提供,则最终执行器的解析如之前所述会默认从容器中获取容器中唯一 type = TaskExecutor 或 name = taskExecutor 的 bean 实例,否则默认 SimpleAsyncTaskExecutor不能提供多个 AsyncConfigurer,否则报错 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() {
Assert.notNull(this.enableAsync, "@EnableAsync annotation metadata was not injected");
// 注册一个 AsyncAnnotationBeanPostProcessor
AsyncAnnotationBeanPostProcessor bpp = new AsyncAnnotationBeanPostProcessor();
bpp.configure(this.executor, this.exceptionHandler);
Class extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
bpp.setAsyncAnnotationType(customAsyncAnnotation);
}
bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
bpp.setOrder(this.enableAsync.getNumber("order"));
return bpp;
}
}
子类 ProxyAsyncConfiguration 中默认注册一个 AsyncAnnotationBeanPostProcessor关于 AsyncAnnotationBeanPostProcessor 前文已经了解,是 ProxyProcessorSupport 的一个核心分支,其下会指定一个 AsyncAnnotationAdvisor 来完成代理通知逻辑实现最终的 Spring Async 总结
至此,对 Spring Async 的使用及其实现原理总结如下:
- 引入 @EnableAsync 注解,最佳实践下应该提供自定义配置类 AsyncConfigurer 来完成 执行器 的配置引入的 @EnableAsync 注解最终会基于 AsyncConfigurer 来配置默认(全局)执行器和 AsyncUncaughtExceptionHandler同时,会注册一个 AsyncAnnotationBeanPostProcessor 到容器中AsyncAnnotationBeanPostProcessor 是 ProxyProcessorSupport 的一个核心分支,其下会指定一个 AsyncAnnotationAdvisorAsyncAnnotationAdvisor 由 AnnotationAsyncExecutionInterceptor 和基于注解匹配的 Pointcut 组成AnnotationAsyncExecutionInterceptor 实现将对应的异步方法交给对应的执行器调度,同时还支持 @Async 的 value 属性指定具体执行器
上一篇:【Spring】Spring Async 的实现原理 2 - AsyncAnnotationAdvisor



