详细解读@EnableAsync注解源码
1. @EnableAsync
/**
* 本注解用于开启Spring的异步方法执行能力,配合@Configuration注解一起使用
*
* 开启之后,Spring默认会对被@Async或@javax.ejb.Asynchronous注解标记的方法进行增强
* 也可以通过本注解的annotation属性来指定自定义的异步注解(此时@Async或@javax.ejb.Asynchronous注解会失效)
*
* Spring默认会通过如下策略来查找线程池,并通过该线程池来执行异步方法:
* 1. 尝试从Spring容器中找到唯一的一个TaskExecutor类型的bean
* 2. 否则,尝试获取一个bean名称为"taskExecutor"且类型为Executor的bean
* 3. 如果还找不到,则创建一个SimpleAsyncTaskExecutor线程池
*
* 此外,如果异步方法的返回值类型为void,那么异步方法无法将异常抛回给调用者
* 默认情况下,这些未被捕获的异常只会被记录到日志中
*
* 如果想要使用自定义的线程池或异常处理器,则可以实现AsyncConfigurer接口,该接口有两个方法:
* 1. getAsyncExecutor():返回自定义的线程池;如果返回null,则沿用原先的策略
* 2. getAsyncUncaughtExceptionHandler():返回自定义的异常处理器;如果返回null,则沿用原先的策略
* 也可以考虑直接继承AsyncConfigurerSupport类
*
* 注意,AsyncConfigurer会在Spring容器启动的时候初始化
* 如果我们的AsyncConfigurer组件依赖了其它bean,则需要将这些依赖声明为懒加载,确保它们能被后置处理器处理到
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class) // 重点!这里导入了AsyncConfigurationSelector组件
public @interface EnableAsync {
/**
* 本属性用于指定自定义的异步注解
* 默认的异步注解为@Async和@javax.ejb.Asynchronous注解
*/
Class<? extends Annotation> annotation() default Annotation.class;
/**
* 本属性用于指定如何对目标方法进行增强
* 默认通过代理进行增强;这意味着如果目标方法是在类内部调用的,则该方法并不会被异步执行
*
* AdviceMode.ASPECTJ则代表通过AspectJ进行增强,这种情况支持类内部调用异步方法
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
* 本属性用于指定是否使用CGLIB代理,而不是JDK动态代理;默认为false
* 注意,本属性只有在mode属性为AdviceMode.PROXY时才有效
*
* 注意,如果将本属性设置为true,则本项设置会影响所有需要被代理的bean,而不仅限于被异步注解标记的bean
* 比如,当本属性为true时,@Transactional注解也会升级为通过CGLIB的方式来创建代理对象
*/
boolean proxyTargetClass() default false;
/**
* 本属性用于指定AsyncAnnotationBeanPostProcessor后置处理器(创建异步代理对象的核心组件)的优先级
* 默认为最低优先级;这么做是为了确保异步增强的逻辑在代理对象的最外层,从而保证异步增强逻辑最先执行
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
2. ImportSelector组件
前面我们已经知道,@EnableAsync注解会导入AsyncConfigurationSelector组件
而AsyncConfigurationSelector类继承自AdviceModeImportSelector类,因此先来看这个父类
2.1. AdviceModeImportSelector
/**
* 本类实现了ImportSelector接口,可以根据实际情况来导入相应的配置类;但本类并不负责实际的配置类导入
* 本类主要负责解析目标注解(即这里的泛型)中的信息,获取到增强模式,让子类根据增强模式来导入对应的配置类
*/
public abstract class AdviceModeImportSelector<A extends Annotation> implements ImportSelector {
public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode";
/**
* 获取目标注解中的配置增强模式的属性的名称,默认为"mode"
*/
protected String getAdviceModeAttributeName() {
return DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME;
}
/**
* 实现ImportSelector接口的抽象方法
*/
@Override
public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 解析到泛型对应的实际类型(即目标注解的Class对象)
Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");
// 获取到该注解指定的具体的配置信息;如果配置类上没有该注解,则这里的attributes为null,此时会抛异常
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()));
}
// 读取注解中的配置增强模式的属性,获取到增强模式
AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName());
// 调用内部的抽象selectImports()方法,让子类根据增强模式来导入对应的配置类
String[] imports = selectImports(adviceMode);
if (imports == null) {
throw new IllegalArgumentException("Unknown AdviceMode: " + adviceMode);
}
return imports;
}
/**
* 根据增强模式来导入对应的配置类
* 可以返回null,代表不支持这种增强模式,或者本组件不知道有这种增强模式
*/
@Nullable
protected abstract String[] selectImports(AdviceMode adviceMode);
}
2.2. AsyncConfigurationSelector
/**
* 本类继承自AdviceModeImportSelector类,并且泛型为EnableAsync类型
*/
public class AsyncConfigurationSelector extends AdviceModeImportSelector<EnableAsync> {
private static final String ASYNC_EXECUTION_ASPECT_CONFIGURATION_CLASS_NAME =
"org.springframework.scheduling.aspectj.AspectJAsyncConfiguration";
/**
* 父类会自动获取到@EnableAsync注解的mode属性值,然后调用本方法
* 本方法会根据这个属性值来导入对应的配置类;这里我们主要关心ProxyAsyncConfiguration配置类
*/
@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;
}
}
}
3. 核心配置类
前面我们已经知道,@EnableAsync(mode = PROXY)注解会导入ProxyAsyncConfiguration配置类
而ProxyAsyncConfiguration类继承自AbstractAsyncConfiguration类,因此先来看这个父类
3.1. AbstractAsyncConfiguration
/**
* 本类是@EnableAsync注解的基础配置类,提供了与异步方法相关的基础配置
*/
@Configuration(proxyBeanMethods = false)
public abstract class AbstractAsyncConfiguration implements ImportAware {
/** 该字段代表@EnableAsync注解的具体信息 */
@Nullable
protected AnnotationAttributes enableAsync;
/** 异步方法执行器的提供者 */
@Nullable
protected Supplier<Executor> executor;
/** 异步方法异常处理器的提供者 */
@Nullable
protected Supplier<AsyncUncaughtExceptionHandler> exceptionHandler;
/**
* 本类实现了ImportAware接口;Spring会自动将@EnableAsync注解的信息注入给本组件
*/
@Override
public void setImportMetadata(AnnotationMetadata importMetadata) {
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());
}
}
/**
* Spring会自动从容器中查找所有AsyncConfigurer组件并将其注入给本组件
*/
@Autowired
void setConfigurers(ObjectProvider<AsyncConfigurer> configurers) {
// 这里要求最多只能有一个AsyncConfigurer组件
Supplier<AsyncConfigurer> configurer = SingletonSupplier.of(() -> {
List<AsyncConfigurer> 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组件的getAsyncExecutor()方法封装成一个Supplier实例并赋给executor字段;exceptionHandler字段同理
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.apply(configurer) : null);
};
}
}
3.2. ProxyAsyncConfiguration
/**
* 本类继承自AbstractAsyncConfiguration类,是实现基于代理的异步方法的核心配置类
*/
@Configuration(proxyBeanMethods = false)
@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组件,并配置如下信息:
// 1. 线程池和异常处理器
// 2. 自定义的异步注解(如果有的话)
// 3. 是否使用CGLIB代理
// 4. 该组件的执行顺序,即优先级
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.<Integer>getNumber("order"));
return bpp;
}
}
4. 后置处理器
还是先来看AsyncAnnotationBeanPostProcessor类的祖先类
4.1. AbstractAdvisingBeanPostProcessor
/**
* 本类主要负责将Advisor组件应用到目标bean上
* Advisor组件是一个增强器,可以看作是切入点和具体的增强逻辑的结合
*/
@SuppressWarnings("serial")
public abstract class AbstractAdvisingBeanPostProcessor extends ProxyProcessorSupport implements BeanPostProcessor {
/** 要应用到目标bean上的增强器 */
@Nullable
protected Advisor advisor;
/** 是否将this.advisor插入到已有的Advisor前面,默认为false */
protected boolean beforeExistingAdvisors = false;
/** 缓存;在判断某个bean是否需要增强时,会先通过该缓存来查询结果 */
private final Map<Class<?>, Boolean> eligibleBeans = new ConcurrentHashMap<>(256);
// 省略setBeforeExistingAdvisors()方法
/**
* 对bean进行前置处理;这里不会做任何处理
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
/**
* 对bean进行后置处理;本方法是本类的核心
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 如果没有增强器,或者目标bean是AOP的基础设施,则不需要处理
if (this.advisor == null || bean instanceof AopInfrastructureBean) {
return bean;
}
// 如果该bean已经被增强过了,并且该bean还未被冻结(即支持继续添加增强器),并且需要对该bean类型进行增强
// 则直接将this.advisor添加到该bean内部的增强器链中;这里会根据this.beforeExistingAdvisors来将其添加到链头或链尾
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
} else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
// 否则,继续判断该bean是否需要增强;如果需要,则创建代理对象,并将this.advisor添加到该代理对象上
if (isEligible(bean, beanName)) {
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass()) {
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != bean.getClass().getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
return proxyFactory.getProxy(classLoader);
}
// 否则,不需要增强
return bean;
}
/**
* 根据bean本身和bean名称判断目标bean是否需要增强;这里直接调用另一个重载方法来判断
*/
protected boolean isEligible(Object bean, String beanName) {
return isEligible(bean.getClass());
}
/**
* 判断目标类型的bean是否需要增强
*/
protected boolean isEligible(Class<?> targetClass) {
// 先查缓存,如果命中,则直接返回结果
Boolean eligible = this.eligibleBeans.get(targetClass);
if (eligible != null) {
return eligible;
}
// 如果没有增强器,则不需要增强
if (this.advisor == null) {
return false;
}
// 否则,通过AopUtils.canApply()方法来判断该bean是否需要增强,并缓存结果
// 这里一般是判断this.advisor底层的poincut是否和目标类型匹配
eligible = AopUtils.canApply(this.advisor, targetClass);
this.eligibleBeans.put(targetClass, eligible);
return eligible;
}
/**
* 创建目标bean的代理对象工厂
* 与代理对象相关的配置直接从本后置处理器中复制(本类继承了ProxyProcessorSupport类)
* 子类可以重写该方法来对代理对象工厂进行自定义的初始化操作
*/
protected ProxyFactory prepareProxyFactory(Object bean, String beanName) {
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
proxyFactory.setTarget(bean);
return proxyFactory;
}
/**
* 钩子方法,允许子类在创建代理对象之前,对代理对象工厂进行自定义的配置
*/
protected void customizeProxyFactory(ProxyFactory proxyFactory) {
}
}
4.2. AbstractBeanFactoryAwareAdvisingPostProcessor
/**
* 本类比较简单,在父类的基础上,额外实现了两个功能:
* 1. 将目标bean的原始类型暴露出去
* 2. 如果目标bean已经通过CGLIB创建代理对象了,则强制使用CGLIB创建代理对象
*
* @see AutoProxyUtils#ORIGINAL_TARGET_CLASS_ATTRIBUTE
* @see AutoProxyUtils#PRESERVE_TARGET_CLASS_ATTRIBUTE
*/
@SuppressWarnings("serial")
public abstract class AbstractBeanFactoryAwareAdvisingPostProcessor extends AbstractAdvisingBeanPostProcessor
implements BeanFactoryAware {
@Nullable
private ConfigurableListableBeanFactory beanFactory;
/**
* 注入bean工厂;只有当bean工厂是ConfigurableListableBeanFactory类型时,才会真正注入
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = (beanFactory instanceof ConfigurableListableBeanFactory ?
(ConfigurableListableBeanFactory) beanFactory : null);
}
/**
* 重写父类的prepareProxyFactory()方法;本方法实现了上面说的两个功能
*/
@Override
protected ProxyFactory prepareProxyFactory(Object bean, String beanName) {
if (this.beanFactory != null) {
AutoProxyUtils.exposeTargetClass(this.beanFactory, beanName, bean.getClass());
}
ProxyFactory proxyFactory = super.prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass() && this.beanFactory != null &&
AutoProxyUtils.shouldProxyTargetClass(this.beanFactory, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
return proxyFactory;
}
/**
* 重写父类的isEligible()方法;如果目标bean是原始对象,则不需要为其创建代理对象
*/
@Override
protected boolean isEligible(Object bean, String beanName) {
return (!AutoProxyUtils.isOriginalInstance(beanName, bean.getClass()) &&
super.isEligible(bean, beanName));
}
}
4.3. AsyncAnnotationBeanPostProcessor
/**
* 本后置处理器会自动将方法的异步执行能力应用到目标bean(即类或方法上有异步注解的bean)上
* 本后置处理器默认检测@Async和@javax.ejb.Asynchronous这两个注解,也支持用户自定义异步注解
* 此外,本后置处理器还支持我们通过异步注解来指定用于执行该异步方法的执行器
*
* 异步方法的增强逻辑封装在AsyncAnnotationAdvisor组件中,即this.advisor字段
* 如果目标bean已经是个代理对象了,则直接将this.advisor添加到代理对象中
* 否则,本后置处理器会为该bean创建一个代理对象,并将this.advisor添加到代理对象中
*
* 对于返回值类型为void的方法来说,该方法在异步执行时抛出的异常无法被调用者捕获,此时该异常会通过异常处理器进行处理
*/
@SuppressWarnings("serial")
public class AsyncAnnotationBeanPostProcessor extends AbstractBeanFactoryAwareAdvisingPostProcessor {
/** 这个常量代表默认的执行器的bean名称:"taskExecutor" */
public static final String DEFAULT_TASK_EXECUTOR_BEAN_NAME =
AnnotationAsyncExecutionInterceptor.DEFAULT_TASK_EXECUTOR_BEAN_NAME;
protected final Log logger = LogFactory.getLog(getClass());
/** 用户自定义的异步方法执行器 */
@Nullable
private Supplier<Executor> executor;
/** 用户自定义的异常处理器 */
@Nullable
private Supplier<AsyncUncaughtExceptionHandler> exceptionHandler;
/** 用户自定义的异步注解 */
@Nullable
private Class<? extends Annotation> asyncAnnotationType;
/**
* 在构造方法中将this.beforeExistingAdvisors字段设置为true,确保AsyncAnnotationAdvisor的增强逻辑最先执行
*/
public AsyncAnnotationBeanPostProcessor() {
setBeforeExistingAdvisors(true);
}
/**
* 配置自定义的异步方法执行器和异常处理器
*/
public void configure(
@Nullable Supplier<Executor> executor,@Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler){
this.executor = executor;
this.exceptionHandler = exceptionHandler;
}
public void setExecutor(Executor executor) {
this.executor = SingletonSupplier.of(executor);
}
public void setExceptionHandler(AsyncUncaughtExceptionHandler exceptionHandler) {
this.exceptionHandler = SingletonSupplier.of(exceptionHandler);
}
/**
* 配置自定义的异步注解
*/
public void setAsyncAnnotationType(Class<? extends Annotation> asyncAnnotationType) {
Assert.notNull(asyncAnnotationType, "'asyncAnnotationType' must not be null");
this.asyncAnnotationType = asyncAnnotationType;
}
/**
* 重写父类的setBeanFactory()方法;在这里完成对this.advisor字段的初始化
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
// 实例化AsyncAnnotationAdvisor组件,并将本类保存的各种配置传递给这个增强器
AsyncAnnotationAdvisor advisor = new AsyncAnnotationAdvisor(this.executor, this.exceptionHandler);
if (this.asyncAnnotationType != null) {
advisor.setAsyncAnnotationType(this.asyncAnnotationType);
}
advisor.setBeanFactory(beanFactory);
this.advisor = advisor;
}
}
5. AsyncAnnotationAdvisor
/**
* 本增强器负责处理异步注解(可以标记在类或方法上)
* 父类AbstractPointcutAdvisor主要定义了一个order字段及其get/set方法,比较简单,不再赘述
*/
@SuppressWarnings("serial")
public class AsyncAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
/** 增强的逻辑,以及切入点 */
private Advice advice;
private Pointcut pointcut;
public AsyncAnnotationAdvisor() {
this((Supplier<Executor>) null, (Supplier<AsyncUncaughtExceptionHandler>) null);
}
public AsyncAnnotationAdvisor(
@Nullable Executor executor, @Nullable AsyncUncaughtExceptionHandler exceptionHandler) {
this(SingletonSupplier.ofNullable(executor), SingletonSupplier.ofNullable(exceptionHandler));
}
/**
* 直接来看这个构造器;这里需指定执行器和异常处理器(可以为null)
*/
@SuppressWarnings("unchecked")
public AsyncAnnotationAdvisor(
@Nullable Supplier<Executor> executor,@Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler){
// 将@Async注解和@javax.ejb.Asynchronous注解(如果有的话)放入asyncAnnotationTypes集合中
Set<Class<? extends Annotation>> asyncAnnotationTypes = new LinkedHashSet<>(2);
asyncAnnotationTypes.add(Async.class);
try {
asyncAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.ejb.Asynchronous", AsyncAnnotationAdvisor.class.getClassLoader()));
} catch (ClassNotFoundException ex) {
// If EJB 3.1 API not present, simply ignore.
}
// 根据执行器和异常处理器来构造一个Advice组件
this.advice = buildAdvice(executor, exceptionHandler);
// 根据@Async注解和@javax.ejb.Asynchronous注解(如果有的话)构造一个Pointcut组件
this.pointcut = buildPointcut(asyncAnnotationTypes);
}
/**
* 设置自定义的异步注解;这里会根据该异步注解重新构造一个Pointcut组件
*/
public void setAsyncAnnotationType(Class<? extends Annotation> asyncAnnotationType) {
Assert.notNull(asyncAnnotationType, "'asyncAnnotationType' must not be null");
Set<Class<? extends Annotation>> asyncAnnotationTypes = new HashSet<>();
asyncAnnotationTypes.add(asyncAnnotationType);
this.pointcut = buildPointcut(asyncAnnotationTypes);
}
/**
* 将bean工厂注入到Advice组件中
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) {
if (this.advice instanceof BeanFactoryAware) {
((BeanFactoryAware) this.advice).setBeanFactory(beanFactory);
}
}
@Override
public Advice getAdvice() {
return this.advice;
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
/**
* 根据执行器和异常处理器来构造Advice组件
* 这里创建的是AnnotationAsyncExecutionInterceptor实例;显然,增强逻辑就封装在这个组件中
*/
protected Advice buildAdvice(
@Nullable Supplier<Executor> executor,@Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler){
AnnotationAsyncExecutionInterceptor interceptor = new AnnotationAsyncExecutionInterceptor(null);
interceptor.configure(executor, exceptionHandler);
return interceptor;
}
/**
* 根据指定的异步注解集合来构造Pointcut组件
* 只要类或方法上有asyncAnnotationTypes中的任意一个注解,就代表需要进行增强
*/
protected Pointcut buildPointcut(Set<Class<? extends Annotation>> asyncAnnotationTypes) {
ComposablePointcut result = null;
for (Class<? extends Annotation> asyncAnnotationType : asyncAnnotationTypes) {
Pointcut cpc = new AnnotationMatchingPointcut(asyncAnnotationType, true);
Pointcut mpc = new AnnotationMatchingPointcut(null, asyncAnnotationType, true);
if (result == null) {
result = new ComposablePointcut(cpc);
} else {
result.union(cpc);
}
result = result.union(mpc);
}
return (result != null ? result : Pointcut.TRUE);
}
}
6. 拦截器
6.1. AsyncExecutionAspectSupport
/**
* 本类是异步方法执行切面的基类,提供了很多工具方法供子类使用
* 本类支持单独为每个异步方法指定各自的执行器(比如通过@Async注解的value属性来指定执行器的bean名称)
* 此外,本类在构造时,还需要指定一个默认执行器
*/
public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
public static final String DEFAULT_TASK_EXECUTOR_BEAN_NAME = "taskExecutor";
protected final Log logger = LogFactory.getLog(getClass());
/** 用于缓存不同方法各自对应的执行器 */
private final Map<Method, AsyncTaskExecutor> executors = new ConcurrentHashMap<>(16);
/** 默认执行器 */
private SingletonSupplier<Executor> defaultExecutor;
/** 异常处理器 */
private SingletonSupplier<AsyncUncaughtExceptionHandler> exceptionHandler;
@Nullable
private BeanFactory beanFactory;
/**
* 构造方法,需指定默认执行器
* 如果给定的执行器为null,则会通过本类的getDefaultExecutor()方法来获取默认执行器
* 并且此时使用SimpleAsyncUncaughtExceptionHandler来处理异常,它仅仅会将异常信息记录到日志中
*/
public AsyncExecutionAspectSupport(@Nullable Executor defaultExecutor) {
this.defaultExecutor = new SingletonSupplier<>(defaultExecutor, () -> getDefaultExecutor(this.beanFactory));
this.exceptionHandler = SingletonSupplier.of(SimpleAsyncUncaughtExceptionHandler::new);
}
/**
* 构造方法,需指定默认执行器和异常处理器
* 如果给定的执行器为null,则会通过本类的getDefaultExecutor()方法来获取默认执行器
*/
public AsyncExecutionAspectSupport(
@Nullable Executor defaultExecutor, AsyncUncaughtExceptionHandler exceptionHandler) {
this.defaultExecutor = new SingletonSupplier<>(defaultExecutor, () -> getDefaultExecutor(this.beanFactory));
this.exceptionHandler = SingletonSupplier.of(exceptionHandler);
}
/**
* 配置默认执行器和异常处理器;处理逻辑和上面两个构造方法类似,不再赘述
*/
public void configure(@Nullable Supplier<Executor> defaultExecutor,
@Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
this.defaultExecutor = new SingletonSupplier<>(defaultExecutor, () -> getDefaultExecutor(this.beanFactory));
this.exceptionHandler = new SingletonSupplier<>(exceptionHandler, SimpleAsyncUncaughtExceptionHandler::new);
}
public void setExecutor(Executor defaultExecutor) {
this.defaultExecutor = SingletonSupplier.of(defaultExecutor);
}
public void setExceptionHandler(AsyncUncaughtExceptionHandler exceptionHandler) {
this.exceptionHandler = SingletonSupplier.of(exceptionHandler);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
/**
* 获取目标方法对应的执行器;最好返回AsyncListenableTaskExecutor实例
*/
@Nullable
protected AsyncTaskExecutor determineAsyncExecutor(Method method) {
// 先查缓存,如果没有命中,则进一步解析
AsyncTaskExecutor executor = this.executors.get(method);
if (executor == null) {
Executor targetExecutor;
// 获取该方法对应的执行器名称;如果获取得到,则在bean工厂中查找对应的bean,否则使用默认执行器
String qualifier = getExecutorQualifier(method);
if (StringUtils.hasLength(qualifier)) {
targetExecutor = findQualifiedExecutor(this.beanFactory, qualifier);
} else {
targetExecutor = this.defaultExecutor.get();
}
// 如果找不到任何执行器,则直接返回null
if (targetExecutor == null) {
return null;
}
// 否则,将该执行器包装成AsyncListenableTaskExecutor类型,并添加到缓存中
executor = (targetExecutor instanceof AsyncListenableTaskExecutor ?
(AsyncListenableTaskExecutor) targetExecutor : new TaskExecutorAdapter(targetExecutor));
this.executors.put(method, executor);
}
return executor;
}
/**
* 获取目标方法对应的执行器的bean名称;如果返回null或空,则会使用默认的执行器
*/
@Nullable
protected abstract String getExecutorQualifier(Method method);
/**
* 根据bean名称查找执行器
*/
@Nullable
protected Executor findQualifiedExecutor(@Nullable BeanFactory beanFactory, String qualifier) {
if (beanFactory == null) {
throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() +
" to access qualified executor '" + qualifier + "'");
}
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(beanFactory, Executor.class, qualifier);
}
/**
* 查找默认执行器;这里删除掉了打印日志的代码
*/
@Nullable
protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
if (beanFactory != null) {
// 尝试返回唯一的一个TaskExecutor类型的bean
try {
return beanFactory.getBean(TaskExecutor.class);
// 如果有多个TaskExecutor类型的bean,则返回名称为"taskExecutor"且类型为Executor的bean
} catch (NoUniqueBeanDefinitionException ex) {
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
} catch (NoSuchBeanDefinitionException ex2) {
// 不存在名称为"taskExecutor"且类型为Executor的bean,此时会返回null
}
// 如果没有TaskExecutor类型的bean,则返回名称为"taskExecutor"且类型为Executor的bean
} catch (NoSuchBeanDefinitionException ex) {
try {
return beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class);
} catch (NoSuchBeanDefinitionException ex2) {
// 不存在名称为"taskExecutor"且类型为Executor的bean,此时会返回null
}
}
}
return null;
}
/**
* 提交任务;returnType代表异步方法的返回值类型
* 如果异步方法返回值类型是Future,则本方法也返回类型;否则本方法返回null
*/
@Nullable
protected Object doSubmit(Callable<Object> task, AsyncTaskExecutor executor, Class<?> returnType) {
if (CompletableFuture.class.isAssignableFrom(returnType)) {
return CompletableFuture.supplyAsync(() -> {
try {
return task.call();
} catch (Throwable ex) {
throw new CompletionException(ex);
}
}, executor);
} else if (ListenableFuture.class.isAssignableFrom(returnType)) {
return ((AsyncListenableTaskExecutor) executor).submitListenable(task);
} else if (Future.class.isAssignableFrom(returnType)) {
return executor.submit(task);
} else {
executor.submit(task);
return null;
}
}
/**
* 处理异步方法抛出的异常
* 如果异步方法返回值类型是Future,则这里会直接抛出该异常;否则会使用异常处理器来处理异常
*/
protected void handleError(Throwable ex, Method method, Object... params) throws Exception {
if (Future.class.isAssignableFrom(method.getReturnType())) {
ReflectionUtils.rethrowException(ex);
} else {
try {
this.exceptionHandler.obtain().handleUncaughtException(ex, method, params);
} catch (Throwable ex2) {
logger.warn("Exception handler for async method '" + method.toGenericString() +
"' threw unexpected exception itself", ex2);
}
}
}
}
6.2. AsyncExecutionInterceptor
/**
* 本类是执行异步方法的核心类,继承自AsyncExecutionAspectSupport类
*
* 从Java语法层面上来说,目标方法的返回值类型可以是任意的
* 但本类要求目标方法的返回值类型必须是void或Future类型(因为其它类型对异步方法来说没有意义)
*
* 如果目标方法返回Future类型,那么调用者获取到的Future对象实际上是代理对象创建的,可用于追踪异步执行结果
* 而原始方法本身也会返回Future对象,此时该Future对象的唯一作用是给代理对象传递返回值
*
* 如果目标方法返回Future类型,那么在执行该方法时抛出的任何异常都可以被调用者获取并处理
* 但如果返回void类型,则这些异常无法传回给调用者,因此,这时候会通过异常处理器来处理
*/
public class AsyncExecutionInterceptor extends AsyncExecutionAspectSupport implements MethodInterceptor, Ordered {
// 省略构造方法
/**
* 拦截目标方法,采用异步的方式来执行该方法
*/
@Override
@Nullable
public Object invoke(final MethodInvocation invocation) throws Throwable {
// 获取到目标类型和目标方法(如果目标方法时桥接方法,则会获取到被桥接的方法)
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
final Method userDeclaredMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
// 用于执行该方法的执行器;获取不到则报错
AsyncTaskExecutor executor = determineAsyncExecutor(userDeclaredMethod);
if (executor == null) {
throw new IllegalStateException(
"No executor specified and no default executor set on AsyncExecutionInterceptor either");
}
// 构建一个异步任务
Callable<Object> task = () -> {
try {
// 调用目标方法
// 如果目标方法返回的是Future类型,则阻塞等待其执行完成,并将执行结果返回
Object result = invocation.proceed();
if (result instanceof Future) {
return ((Future<?>) result).get();
}
} catch (ExecutionException ex) {
// 出现异常时,判断目标方法是否返回Future类型,是则直接抛出该异常,否则调用异常处理器来处理
handleError(ex.getCause(), userDeclaredMethod, invocation.getArguments());
} catch (Throwable ex) {
// 出现异常时,判断目标方法是否返回Future类型,是则直接抛出该异常,否则调用异常处理器来处理
handleError(ex, userDeclaredMethod, invocation.getArguments());
}
return null;
};
// 提交任务
return doSubmit(task, executor, invocation.getMethod().getReturnType());
}
/**
* 获取目标方法对应的执行器的bean名称
* 这里直接返回null,代表本组件不支持为每个异步方法单独指定各自的执行器
*/
@Override
@Nullable
protected String getExecutorQualifier(Method method) {
return null;
}
/**
* 查找默认执行器
* 这里沿用了父类的搜索逻辑,如果搜索不到,则创建一个SimpleAsyncTaskExecutor实例作为兜底
*/
@Override
@Nullable
protected Executor getDefaultExecutor(@Nullable BeanFactory beanFactory) {
Executor defaultExecutor = super.getDefaultExecutor(beanFactory);
return (defaultExecutor != null ? defaultExecutor : new SimpleAsyncTaskExecutor());
}
/**
* 本拦截器的优先级是最高的,确保异步执行的逻辑比其它增强逻辑更先执行
*/
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
}
6.3. AnnotationAsyncExecutionInterceptor
/**
* 本类在AsyncExecutionInterceptor的基础上,支持通过@Async注解来指定执行器
* 需要注意的是,即使我们使用了自定义的异步注解,本类也只解析@Async注解,所以我感觉这里有点问题
*/
public class AnnotationAsyncExecutionInterceptor extends AsyncExecutionInterceptor {
// 省略构造方法
/**
* 获取目标方法对应的执行器的bean名称
* 这里优先获取方法上的@Async注解,如果没有则获取类上的@Async注解,然后返回其value属性值
*/
@Override
@Nullable
protected String getExecutorQualifier(Method method) {
// Maintainer's note: changes made here should also be made in
// AnnotationAsyncExecutionAspect#getExecutorQualifier
Async async = AnnotatedElementUtils.findMergedAnnotation(method, Async.class);
if (async == null) {
async = AnnotatedElementUtils.findMergedAnnotation(method.getDeclaringClass(), Async.class);
}
return (async != null ? async.value() : null);
}
}