前言
上一篇文章主要讲了EnableAsync
注解是如何创建aop并生效的,这一篇讲springboot
是如何处理被拦截的方法的;
正文
1.0 AsyncExecutionInterceptor类
这里看AsyncExecutionInterceptor
类中的invoke
方法,源码如下:
1 |
|
- 获取拦截的方法
- 根据被拦截的方法来选取执行异步任务的执行器
- 构建任务(添加异常的处理方式)
- 执行构建的任务并返回任务执行结果
2.0 AsyncExecutionAspectSupport类
该类的determineAsyncExecutor
方法会返回一个AsyncTaskExecutor
,也就是返回一个执行异步任务的线程池;
这里来看看上一个类中的determineAsyncExecutor
方法源码:
1 |
|
- 根据方法选取
executors
缓存中的执行器 - 该方法是获取被拦截方法的
Async
注解的value
,具体的源码在AnnotationAsyncExecutionInterceptor
类中 - 如果注解有
value
值,则从beanFactory
中获取该value
值的bean
(根据注解中的值选取Executor
执行器) - 获取默认执行器,该默认值是在构造方法时设置的,后面详解;
- 转换
targetExecutor
为executor
- 将
executor
存入缓存 - 返回
executor
2.1 getExecutorQualifier方法
该方法是返回参数方法上的Async
注解的value
值(executor
的bean
的name
),该方法的源码在AnnotationAsyncExecutionInterceptor
类中:
1 |
|
- 获取方法上的
Async
注解信息 - 若1为
null
,则根据方法的类来获取Async
注解信息 - 返回
Async
的注解值
2.2 defaultExecutor值
在2.0中的第四步调用了defaultExecutor,获取默认的Executor:
1 |
|
那么这个defaultExecutor的值是什么时候初始化的呢??? 来看看AsyncExecutionAspectSupport的构造方法:
1 |
|
先讲解这个方法:
这里是在给defaultExecutor
属性和exceptionHandler
属性赋值;
那么为什么要看这个构造方法呢??? 接下来返回到AsyncAnnotationAdvisor类的buildAdvice方法(参考上一篇文章:springboot异步线程(三)源码解析(一)),最终调用了上方的构造方法
1 |
|
我们可以看见调用AnnotationAsyncExecutionInterceptor
构造方法的参数为null
;
接下来看看AsyncExecutionAspectSupport
类的构造方法中给defaultExecutor
属性赋值时的另一个方法getDefaultExecutor
方法,该方法就是获取BeanFactory
中的Executor
,这里选关键代码:
1 |
|
该方法被子类AsyncExecutionInterceptor重写:
1 |
|
3.0 doSubmit方法
该方法是执行上边1.0的第四步:将拦截的方法封装任务并交由默认执行器执行,最后返回结果;
该方法的源码在AsyncExecutionAspectSupport类,源码如下:
1 |
|
总结
这里主要写一下异步任务选择执行器的大概流程吧:
- 检查AsyncConfigurer接口是否有实现类
- 查看Async注解是否带有指定执行器beanName,也就是Async注解的value值
- 根据TaskExecutor(专门为 异步任务设计的)类别查找beanFactory中的bean(执行器)
- 根据beanName为taskExecutor且类型为Executor来查找beanFactory中的bean(执行器)
- 新建一个 SimpleAsyncTaskExecutor执行器
在我的文章:springboot异步线程(二) 中有讲到:springboot2.1之后的版本与springboot2.1之前的版本的区别,这里也就不细说了;
最后
我还是我,我在努力,Take your time。