简介
在上篇文章spring框架中的@Async使用以及原理浅析 (1),我们介绍了@Async
注解的使用方式,本文将介绍其实现原理,大致分为3块:
- 应用启动时。
- 构造业务类时。
- 异步方法执行时。
应用启动
首先,要使用@Async
,必须先用@EnableAsyc
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
/**
* 这里可以自定义使方法异步化的注解,一般我们直接用@Async就行
*/
Class<? extends Annotation> annotation() default Annotation.class;
/**
* 实现异步代理的切面模式,一种是jdk动态代理(默认使用),一种是ASPECJ
*/
AdviceMode mode() default AdviceMode.PROXY;
}
其引入了AsyncConfigurationSelector
,这是一个选择器,根据@EnableAsync
中的mode
来决定使用哪种异步配置。由于使用我们的配置是AdviceMode.PROXY
,所以这里返回ProxyAsyncConfiguration
的名称,表示后续会构建ProxyAsyncConfiguration
。
public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";
@Override
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;
}
}
}
@Configuration
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyAsyncConfiguration extends AbstractAsyncConfiguration {
protected Executor executor; // 继承自AbstractAsyncConfiguration
protected AsyncUncaughtExceptionHandler exceptionHandler; // 继承自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 bpp = new AsyncAnnotationBeanPostProcessor();
Class<? extends Annotation> customAsyncAnnotation = this.enableAsync.getClass("annotation");
if (customAsyncAnnotation != AnnotationUtils.getDefaultValue(EnableAsync.class, "annotation")