Spring之@Async注解

本文详细解析了Spring框架中@Async和@EnableAsync注解的工作原理及其实现机制,包括配置、注解处理过程、异步任务执行流程等关键内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值