91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

關于Spring注解@Async引發其他注解失效的解決

發布時間:2020-10-18 14:18:57 來源:腳本之家 閱讀:241 作者:atheva 欄目:編程語言

概述

在前面一篇文章中,介紹,在一個Bean中注入自己,如果有@Async和@Transaction,如果使用@Autowire注入自身,會報循環依賴,如果使用BeanFactoryAware注入自己,會使得@Transaction失效。 例如:

@Service
public class MyService implements BeanFactoryAware{
 private MyService self;
 
 //事務注解無效
 @Transactional
 public void notWork() {
  ...
 }
 
 @Async
 public Future async(){
  ...
 }
 
 
 @Override
 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
  self= beanFactory.getBean(MyService.class);
 }
}

當時只是簡單提了一下,這篇文章就是來介紹為什么會失效。

一般情況

造成上面的情況需要滿足以下條件:

  1. 有@Async和其他類似@Transaction注解
  2. 自己類在BeanFactoryAware中,通過BeanFactory獲取自己

造成的結果:除@Async外的注解生效,其他的都不生效,如下圖

關于Spring注解@Async引發其他注解失效的解決

而正常代理的應該是下圖:

關于Spring注解@Async引發其他注解失效的解決

原因

首先想到的是@Async注解的處理方式可能和其他的不一樣。在AsyncAnnotationBeanPostProcessor的實現中(具體代碼是在其父類AbstractAdvisingBeanPostProcessor),發現一個問題,

正常情況下,進來的bean已經是被代理的動態代理類,而失效的時候,進來的確實實際的類,如下圖:

關于Spring注解@Async引發其他注解失效的解決

然后在分析下代碼,如果是實際的類,走到69行的時候,返回是true,把@Aysnc的Advisor加入到動態道理中,而如果是實際的類,走到83行的時候,就會創建代理類,只把@Aysnc的advisor加入到動態代理中,所已諸如@Transaction就會失效。

為什么進來的不是代理類

其實唯一的區別就是BeanFactoryAware中,是否通過了BeanFactory獲取了自己。那為什么使用BeanFactory獲取了自己,后續的BeanPostProcessor中就不是代理了?如果熟悉Spring @Transaction加載機制的就知道,諸如@Transaction,@Retryable 注解的動態代理創建是在AnnotationAwareAspectJAutoProxyCreator中創建的。通過debug發現,經過AnnotationAwareAspectJAutoProxyCreator后,我們的動態代理竟然沒有加上。

再看一下AnnotationAwareAspectJAutoProxyCreator中的實現,但是經過他卻沒有生成代理類。原因竟然是提前暴露的Map里面竟然有“myService”,

關于Spring注解@Async引發其他注解失效的解決

他是什么時候暴露出來的呢?其實就是在

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
 self= beanFactory.getBean(MyService.class);
}

那么,一切水落石出了,在實例MyService中,觸發了BeanFactoryAware,通過beanFactory.getBean(MyService.class);中創建了代理類(tips:當前代理類并沒有包含@Async的Adivisor),因為現在Spring其實正是在創建MyService這個Bean,還沒有放入到BeanFactory中。然后我們再這個過程中又觸發了一次beanFactory.getBean(MyService.class);導致創建代理并返回后,加入到了到了提前暴露的map中。導致后面的一系列問題。感覺有點繞。看圖說話:

正常情況,應該是如下流程:

關于Spring注解@Async引發其他注解失效的解決

異常情況卻是這樣的

關于Spring注解@Async引發其他注解失效的解決

小結

正常情況下,還是使用@Autowire來注入把(如果使用Autowire,上述情況直接回拋出循環依賴)。當然,出現了問題,也是不能放過了,要知其然還要知其所以然!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新巴尔虎右旗| 洛隆县| 通河县| 七台河市| 沾化县| 古浪县| 吉林省| 保定市| 苏尼特右旗| 黄山市| 土默特左旗| 杭锦旗| 张掖市| 汉寿县| 浮山县| 陆丰市| 东乌珠穆沁旗| 隆尧县| 兴海县| 界首市| 丁青县| 右玉县| 武宁县| 通江县| 山丹县| 延庆县| 杭州市| 沂源县| 靖安县| 南平市| 黎川县| 绥滨县| 洪洞县| 宁蒗| 富宁县| 钟山县| 芜湖县| 塔河县| 台湾省| 乐平市| 千阳县|