Spring异步任务@Async的默认线程池执行器是如何初始化的

Spring异步任务@Async的默认线程池执行器,是从哪里来?是如何初始化的?

结论先行

异步任务@Async的默认线程池执行器是通过TaskExecutionAutoConfiguration#applicationTaskExecutor自动注入的。

异步任务的线程池执行器是如何初始化的?

从异步调用拦截器作为切入点,看看异步调用拦截器的调用流程是咋样的?

AsyncExecutionInterceptor#invoke

org.springframework.aop.interceptor.AsyncExecutionInterceptor

异步任务的执行调用入口

AsyncExecutionInterceptor#invoke ---> AsyncExecutionAspectSupport#determineAsyncExecutor

AsyncExecutionAspectSupport#determineAsyncExecutor

AsyncExecutionAspectSupport#determineAsyncExecutor ---> 先调用getExecutorQualifier(method),再调用this.defaultExecutor.get()

AnnotationAsyncExecutionInterceptor#getExecutorQualifier

getExecutorQualifier方法在AnnotationAsyncExecutionInterceptor#getExecutorQualifier被覆盖重写

AnnotatedElementUtils.findMergedAnnotation(method, Async.class)会返回@Async注解实例。
AnnotatedElementUtils.findMergedAnnotation(method, Async.class)是如何查找@Async注解?会起另一篇文章说明。

defaultExecutor是如何初始化的?

接下来,看看defaultExecutor是如何初始化的?
defaultExecutor初始化 ---> getDefaultExecutor(this.beanFactory)

AsyncExecutionAspectSupport#getDefaultExecutor

AsyncExecutionAspectSupport#getDefaultExecutor ---> 先调用beanFactory.getBean(TaskExecutor.class),再调用beanFactory.getBean(DEFAULT_TASK_EXECUTOR_BEAN_NAME, Executor.class)

AsyncExecutionInterceptor#getDefaultExecutor覆盖重写了本方法

debug调试发现super.getDefaultExecutor(beanFactory)已返回默认的执行器实例,说明是从beanFactory里获取的。
【猜想】可能是在哪个AutoConfiguration里自动注入的?

查看beanFactory里注入的bean实例列表,发现如下线索。
TaskExecutionAutoConfiguration

复制代码
applicationTaskExecutor -> {BeanDefinitionHolder@17669} "Bean definition with name 'applicationTaskExecutor' and aliases [taskExecutor]: Root bean: class [null]; scope=singleton; abstract=false; lazyInit=true; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration; factoryMethodName=applicationTaskExecutor; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/task/TaskExecutionAutoConfiguration.class]"

DefaultExecutor是否从TaskExecutionAutoConfiguration实例化而来

实例内存地址id是否一样?

TaskExecutionAutoConfiguration#applicationTaskExecutor

org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration

通过debug验证猜想,根据实例内存地址id,就是这里生成的。

TaskExecutionAutoConfiguration#taskExecutorBuilder

TaskExecutionAutoConfiguration#applicationTaskExecutor

实例内存地址id都是 ThreadPoolTaskExecutor@11620

org.springframework.beans.factory.support.SimpleInstantiationStrategy#instantiate

AsyncExecutionInterceptor#getDefaultExecutor

org.springframework.aop.interceptor.AsyncExecutionInterceptor#getDefaultExecutor

相关推荐
_Evan_Yao21 小时前
Redis 缓存穿透、击穿、雪崩,一次讲清!
java·spring·mybatis
梓豪csd21 小时前
消息订阅中心:谁该收到哪条通知
java·开发语言·人工智能·低代码·自动化·1024程序员节
秋饼21 小时前
Spring AI 2.1 Message Parts 深度实战:推理签名回放与跨轮记忆持久化的源码级落地
java·ai·技术分享·后端开发
thefool1122661 天前
TCP 1
java·1024程序员节
paopaokaka_luck1 天前
宠物门店经营管理系统(销售与库存联动、进货自动记账、 退换与退款关联、员工个人业绩、ECharts 经营分析、滞销识别与客户分层、宠物档案年龄计算)
前端·javascript·spring boot·mysql·echarts·mybatis·1024程序员节
金銀銅鐵1 天前
[Java] 用 GUI 展示 EnumSet 增减元素时的内部变化(下)
java·后端·ai编程
AI人工智能+电脑小能手1 天前
一次请求打几个下游,这个Java并行任务工具类6个方法按序聚合
java·线程池·并发编程·1024程序员节·批量处理·并行任务
paopaokaka_luck1 天前
心理咨询管理系统(WebSocket实时沟通、基于用户的协同过滤、 ECharts多维分析、 预约业务流程、预约校验与定时处理)
java·vue.js·spring boot·mysql·spring·echarts·1024程序员节
2301_32241428041 天前
springboot农产品交易平台的设计与实现08055-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·spring boot·redis·mysql·tomcat·maven·mybatis
考虑考虑1 天前
JDK26的JEP 500属性
java·后端·java ee