Spring @Async 原理
@EnableAsync
开启异步功能需要 @EnableAsync
注解,可以以此作为切入点。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 导入了 AsyncConfigurationSelector,很重要
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
// 可以自定义异步的注解来代替 @Async,一般不会使用
Class<? extends Annotation> annotation() default Annotation.class;
// 是否使用 CGLIB 代理,这个配置会影响所有使用代理的地方,不止是 @Async
boolean proxyTargetClass() default false;
// 代理的 advice 是使用 JDK 还是使用 ASPECTJ,一般不修改
AdviceMode mode() default AdviceMode.PROXY;
/**
* Indicate the order in which the {@link AsyncAnnotationBeanPostProcessor}
* should be applied.
* <p>The default is {@link Ordered#LOWEST_PRECEDENCE} in order to run
* after all other post-processors, so that it can add an advisor to
* existing proxies rather than double-proxy.
*/
// 决定 AsyncAnnotationBeanPostProcessor 被应用的顺序,默认是最低优先级,在运行完其他 post-processors 后再被应用
int order() default Ordered.LOWEST_PRECEDENCE;
}
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) {
// 向 Spring 注入一个 ProxyAsyncConfiguration
case PROXY -> new String[] {
ProxyAsyncConfiguration.class.getName()};
case ASPECTJ -> new String[] {
ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME};
};
}
}
AsyncConfigurationSelector
继承于 AdviceModeImportSelector
,可以通过解析子类的泛型,泛型一般是 EnableXXX
注解类型,比如 AsyncConfigurationSelector
的泛型是 AdviceModeImportSelector<EnableAsync>
;CachingConfigurationSelector
的泛型是 AdviceModeImportSelector<EnableCaching>
,然后根据 AdviceMode
选择要 import 的配置。
public abstract class AdviceModeImportSelector<A extends Annotation> implements ImportSelector {
// EnableAsync、EnableCaching 注解中都会有一个 mode 属性代表 AdviceMode
public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode";
protected String getAdviceModeAttributeName() {
return DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME;
}
@Override
public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 获取类上的泛型,即 EnableAsync
Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");
// 获取 EnableAsync 的属性
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
if (attributes == null) {
throw new IllegalArgumentException(String.format(
"@%s is not present on importing class '%s' as expected",
annType.getSimpleName(), importingClassMetadata.getClassName()));
}
// 获取 EnableAsync 的 mode 属性
AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName());
// 调用 AsyncConfigurationSelector 的 selectImports
String[] imports = selectImports(adviceMode);
if (imports == null) {
throw new IllegalArgumentException("Unknown AdviceMode: " + adviceMode);
}
return imports;
}
@Nullable
protected abstract String[] selectImports(AdviceMode adviceMode);
}
ProxyAsyncConfiguration
主要就是注册一个 AsyncAnnotationBeanPostProcessor
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
// 注册一个 AsyncAnnotationBeanPostProcessor
@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();
// 配置线程池、错误处理器 AsyncUncaughtExceptionHandler
bpp.configure(this.executor, this.exceptionHandler);
// this.enableAsync 是 EnableAsync 的属性有,由父类 AbstractAsyncConfiguration 赋值
Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
// 设置自定义的异步注解
if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")) {
bpp.setAsyncAnnotationType(customAsyncAnnotation);
}
// 是否使用 CGLIB
bpp.setProxyTargetClass(this.enableAsync.getBoolean("proxyTargetClass"));
// Order
bpp.setOrder(this.enableAsync.<Integer>getNumber("order"));
return bpp;
}
}
AbstractAsyncConfiguration
@Configuration(proxyBeanMethods = false)
public abstract class AbstractAsyncConfiguration implements ImportAware {
// EnableAsync 的属性
@Nullable
protected AnnotationAttributes enableAsync;
// 线程池
@Nullable
protected Supplier<Executor> executor;
// 异常处理器
@Nullable
protected Supplier<AsyncUncaughtExceptionHandler> exceptionHandler;
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
// EnableAsync 的属性
this.enableAsync = AnnotationAttributes.fromMap(
importMetadata.getAnnotationAttributes(EnableAsync.class.getName()));
if (this.enableAsync == null) {
throw new IllegalArgumentException(
"@EnableAsync is not present on importing class " + importMetadata.getClassName());
}
}
/**
* Collect any {@link AsyncConfigurer} beans through autowiring.
*/
@Autowired
void setConfigurers(ObjectProvider<AsyncConfigurer> configurers) {
// 获取唯一的线程池、异常处理器的配置
Supplier<AsyncConfigurer> configurer = SingletonSupplier.of(() -> {
List<AsyncConfigurer> candidates = configurers.stream().toList();
if (CollectionUtils.isEmpty(candidates)) {
return null;
}
if (candidates.size() > 1) {
throw new IllegalStateException("Only one AsyncConfigurer may exist");
}
return candidates.get(0);
});
// 配置线程池、异常处理器
this.executor = adapt(configurer, AsyncConfigurer::getAsyncExecutor);
this.exceptionHandler = adapt(configurer, AsyncConfigurer::getAsyncUncaughtExceptionHandler);
}
private <T> Supplier<T> adapt(Supplier<AsyncConfigurer> supplier, Function<AsyncConfigurer, T> provider) {
return () -> {
AsyncConfigurer configurer = supplier.get();
return (configurer != null ? provider.