1. 前言
@EnableAsync 注解需要和 @Async 注解搭配使用,这篇博文我们就分析这两个注解是如何搭配使用的
2. @EnableAsync 注解
@EnableAsync 注解使用 @Import 注解,注入的类型为 AsyncConfigurationSelector
2.1 @Import 注解
@Import 注解注入的类一般有以下特征:
实现 ImportSelector 接口 | 会在解析阶段执行 selectImports 方法,方法返回的类名数组,会被解析成 BeanDefinition 对象,进而被实例化成 bean |
实现 ImportBeanDefinitionRegistrar 接口 | 会在解析阶段执行 registerBeanDefinitions 方法,一般会注册 BeanDefinition 对象 |
配置类 | 以配置类进行解析 |
2.2 AsyncConfigurationSelector
AsyncConfigurationSelector 实现 ImportSelector 接口,会在 Spring 解析过程中执行 selectImports 方法,通过方法调用,最终会调用 AsyncConfigurationSelector 的 selectImports 方法
2.2.1 AsyncConfigurationSelector#selectImports
2.2.2 ProxyAsyncConfiguration
2.2.2.1 获取 @EnableAsync 注解配置的属性
ProxyAsyncConfiguration 继承 AbstractAsyncConfiguration 类,AbstractAsyncConfiguration 实现 ImportAware 接口,所以在 bean 的实例化过程中会执行 setImportMetadata 方法,通过该方法可以获取 @EnableAsync 注解配置的属性
2.2.2.2 asyncAdvisor 方法
通过 asyncAdvisor 方法,ProxyAsyncConfiguration 会定义一个类型为 AsyncAnnotationBeanPostProcessor 的 bean,该 bean 是一个 BeanPostProcessor。BeanPostProcessor 可以作用于普通 bean 生命周期的以下几个阶段:
- postProcessBeforeInitialization
- postProcessMergedBeanDefinition
- postProcessAfterInitialization
- postProcessPropertyValues
- postProcessBeforeInstantiation
- postProcessAfterInstantiation
2.3 AsyncAnnotationBeanPostProcessor
2.3.1 setBeanFactory
AsyncAnnotationBeanPostProcessor 实现 BeanFactoryAware 接口,所以会在实例化过程中执行 setBeanFactory 方法,所以 AsyncAnnotationBeanPostProcessor 存在一个类型为 AsyncAnnotationAdvisor 的属性
2.3.2 AbstractAdvisingBeanPostProcessor#postProcessAfterInitialization
如果 bean 已经是一个代理对象则给 Advised 对象(代理对象)添加一个 Advisor,否则进行动态代理
2.4 DynamicAdvisedInterceptor#intercept
代理方式可能是 JDK 也有可能是 CGLIB,但是整体逻辑很类似,这里就以 CGLIB 演示
2.4.1 DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
在上文的分析中,如果存在 @EnableAsync 注解,则会存在一个类型为 AsyncAnnotationAdvisor 的 Advisor,AsyncAnnotationAdvisor 是 PointcutAdvisor 的子类,所以会进入第一个分支
2.4.1.1 AsyncAnnotationAdvisor 的构造方法
综上所述,得出以下结论:
- Pointcut 类型为 ComposablePointcut
- ClassFilter 类型为 AnnotationClassFilter
-
MethodMatcher 类型为 MethodMatcher.TRUE
2.4.1.2 AnnotationClassFilter#matches
即类上存在 @Async 注解则返回 true
2.4.1.3 MethodMatcher.TRUE#matches
MethodMatcher.TRUE 的 matches 方法一定会返回 true,即 AnnotationClassFilter 的 matches 方法返回 true,就会通过 DefaultAdvisorAdapterRegistry 的 getInterceptors 方法返回 Interceptors
2.4.1.4 DefaultAdvisorAdapterRegistr#getInterceptors
最终通过 AsyncAnnotationAdvisor 的 getAdvice 方法返回 Advice 对象
我们再次回顾 AsyncAnnotationAdvisor 的构造方法
最终返回的 Interceptor 的类型是 AnnotationAsyncExecutionInterceptor
2.5 AnnotationAsyncExecutionInterceptor
2.5.1 AnnotationAsyncExecutionInterceptor#invoke
2.5.1.1 AsyncExecutionAspectSupport#determineAsyncExecutor
2.5.1.1.1 AnnotationAsyncExecutionInterceptor#getExecutorQualifier
从类上或者方法查找 @Async 注解,如果存在就返回其 value,否则抛出异常
2.5.1.1.2 AnnotationAsyncExecutionInterceptor#findQualifiedExecutor
如果 @Async 注解指定了 value 则从 beanFactory 中获取指定 name 的 bean
2.5.1.1.3 defaultExecutor
如果 @Async 注解指定 未指定 value ,则使用 defaultExecutor
通过源码得出结论:如果有且仅有一个类型为 TaskExecutor 的 bean,则视为 defaultExecutor,如果存在多个类型为 taskExecutor 的 bean 或者 不存在类型为 taskExecutor 的 bean,则查找 beanFactory 中类型为 Executor,名称为 taskExecutor 的 bean 为 defaultExecutor