Async

Async 使用

@Async的使用非常简单。只需在配置类上加上 @EnableAsync 就可以直接使用。

​ 如果需要指定线程池执行,需要在配置类中指定线程池别名。

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
@EnableAsync
public class AsyncExecutorQualifiedByNameConfig {

@Bean
@Qualifier("userAccountCreateEventAsyncThreadPool")
public Executor userAccountCreateEventAsyncThreadPool() {
//线程池
ThreadPoolExecutor poolExecutor = ThreadPoolGenerator.newCallerRunSyncQueuePool("userAccountCreateEventAsyncThreadPool", 20, 50);
return poolExecutor;
}
}
1
2
3
4
5
// 指定线程池异步执行
@Async("userAccountCreateEventAsyncThreadPool")
public void onApplicationEvent(UserAccountCreateEvent event) {
......
}

实现分析

​ 一般情况下都是这些@EnableXXX注解里面有一个@Import注解,然后这个@Import注解会导入一个类,这个被导入的类一般是个配置类(类上面有@Configuration注解),然后里面配置了需要用到的类的Bean。

org.springframework.scheduling.annotation.EnableAsync:

1
2
3
4
5
6
7
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
......
}

org.springframework.scheduling.annotation.AsyncConfigurationSelector:

​ 该类实现了ImportSelector接口,最终会调用到AsyncConfigurationSelector实现的selectImports方法,这个方法可能返回 ProxyAsyncConfiguration 类的全限定名或者 org.springframework.scheduling.aspectj.AspectJAsyncConfiguration 或者null,如果不是null的话,后面会解析这些类上面的注解(两个类都是配置类,即类上面有@Configuration注解),然后将读取到的BeanDefinitino注册到BeanFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";
@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;
}
}
}