javascript
Spring @Async注解
1.@Async注解使用條件
@Async源碼- @Async注解一般用在類的方法上,如果用在類上,那么這個類所有的方法都是異步執行的;
- 所使用的@Async注解方法的類對象應該是Spring容器管理的bean對象;
- 調用異步方法類上需要配置上注解@EnableAsync
2.實現原理
為了更基礎的分析異步調用背后的實現原理,這里選擇使用xml配置文件的方式。使用xml配置文件方式時,一般會配置如下元素:
<task:annotation-driven executor="myExecutor" exception-handler="exceptionHandler"/> <task:executor id="myExecutor" pool-size="5"/> <bean id="exceptionHandler" class="com.abc.MyAsynExceptionHandler"/>2.1 task標簽
一般對于這種標簽的解析都會有相應的NamespaceHandler,根據Spring命名的套路查找TaskNamespaceHandler類,具體代碼如下:
TaskNamespaceHandler(1)executor元素對應的ExecutorBeanDefinitionParser
ExecutorBeanDefinitionParser該類從parse方法追蹤具體的實現邏輯,這個類主要是根據executor元素中的配置,例如pool-size創建一個TaskExecutorFactoryBean對象,而在TaskExecutorFactoryBean中間接使用ThreadPoolExecutor創建了一個線程池,這個線程池會在annotation-driven元素解析類中用到。
在TaskExecutorFactoryBean中可以看出:
TaskExecutorFactoryBean(2)annotation-driven元素處理類AnnotationDrivenBeanDefinitionParser
AnnotationDrivenBeanDefinitionParser默認情況下,如果沒有配置mode屬性,其值默認是proxy,使用代理模式,會創建一個AsyncAnnotationBeanPostProcessor,然后解析executor屬性值和exception-handler屬性值并將其設置到AsyncAnnotationBeanPostProcessor中。
該類實現了BeanFactoryAware接口,所以在其實例化時會執行setBeanFactory方法:
創建AsyncAnnotationAdvisor對象,即給線程池創建了一個異步注解切面
AsyncAnnotationAdvisor主要就是使用上面提到的executor元素解析得到的線程池和異常處理創建通知,使用@Async注解創建切入點
進入構建通知的方法中,buildAdvice(executor, exceptionHandler)
AnnotationAsyncExecutionInterceptor間接實現了MethodInterceptor接口,而MethodInterceptor是AOP中切入點的處理器,處理器中最終被調用的是invoke方法,下面是invoke方法的源碼:
AsyncExecutionInterceptordoSubmit方法源碼:
AsyncExecutionAspectSupportAsyncAnnotationBeanPostProcessor類還間接實現了BeanPostProcessor接口,也就是說在bean初始化之前和之后會分別執行postProcessBeforeInitialization方法和postProcessAfterInitialization方法,而AsyncAnnotationBeanPostProcessor類的這兩個方法是從AbstractAdvisingBeanPostProcessor類中繼承來的,這里重點分析postProcessAfterInitialization方法,具體代碼如下:
AbstractAdvisingBeanPostProcessor創建代理可以使用Cglib或者jdk動態代理,這里選擇JdkDynamicAopProxy深入分析,代理的創建這里就不深入分析了,這里重點關注一下調用代理時真正執行的invoke方法,方法體內容比較多,這里看一下如下重要代碼:
JdkDynamicAopProxy?
總結
Spring容器啟動初始化bean時,判斷類中是否使用了@Async注解,創建切入點和切入點處理器,根據切入點創建代理,在調用@Async注解標注的方法時,會調用代理,執行切入點處理器invoke方法,將方法的執行提交給線程池,實現異步執行。
所以,需要注意的一個錯誤用法是,如果A類的a方法(沒有標注@Async)調用它自己的b方法(標注@Async)是不會異步執行的,因為從a方法進入調用的都是它本身,不會進入代理
作者:LZhan
鏈接:https://www.jianshu.com/p/69a7bbdaceeb
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
總結
以上是生活随笔為你收集整理的Spring @Async注解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如果张东升是个程序员
- 下一篇: gradle idea java ssm