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