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

溫馨提示×

溫馨提示×

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

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

Spring事務、異步和循環依賴的關系有哪些

發布時間:2021-10-19 13:58:27 來源:億速云 閱讀:116 作者:iii 欄目:web開發

這篇文章主要介紹“Spring事務、異步和循環依賴的關系有哪些”,在日常操作中,相信很多人在Spring事務、異步和循環依賴的關系有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Spring事務、異步和循環依賴的關系有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

前言

在循環依賴中有一種循環依賴,就是自注入:自己依賴自己。

Spring事務、異步和循環依賴的關系有哪些

事務的自注入

在 Spring 自調用事務失效,你是怎么解決的? 有小伙伴提出可以自己注入自己來解決事務失效。

具體使用方式如下:

@Slf4j @Service public class OrderBizServiceImpl implements OrderBizService {      // 注入自己     @Autowired     private OrderBizService orderBizService;      @Override     public void callBack() throws Exception {          // 一系列的邏輯          // 需要事務操作更新訂單和用戶金額         orderBizService.updateOrderStatusAndUserBalance();     }      @Override     @Transactional(rollbackFor = Exception.class)     public void updateOrderStatusAndUserBalance() throws Exception {         // 內部是事務邏輯     } }

是不是發現很神奇的事情,事務生效了。

其實這里注入自己,其實是注入的一個代理對象,調事務,也是調的代理對象的事務,所以事務生效。

Spring 事務失效原因:

事務只能應用到 public 方法上才會有效;事務需要從外部調用,Spring 自調用會失效;建議事務注解 @Transactional  一般添加在實現類上。

異步的自注入

發現 @Transactional 注解可以自注入解決事務失效的問題,在某次開發中,自然而然想到 @Async  異步是不是也可以自注入解決循環依賴的問題。

NO, NO, NO……

事實告訴我們是不可以的!

Spring事務、異步和循環依賴的關系有哪些

從錯誤開始著手:

Spring事務、異步和循環依賴的關系有哪些

拋出異常部分 doCreateBean

開始往上面反推 exposedObject == bean 是這一塊出了問題。

也就是說異步的時候,再次從二級緩存中獲取的和初始的不相同。

Object earlySingletonReference = getSingleton(beanName, false);

Spring事務、異步和循環依賴的關系有哪些

從二級緩存再次獲取 Bean

這一次獲取的時候發現不同所以報錯。

那就開始 Debug, 按照循環依賴的邏輯,執行到 populateBean 時,屬性賦值,發現有依賴自己,此時會創建自己。

執行 singleton.getObject 方法

Spring事務、異步和循環依賴的關系有哪些

getEarlyBeanReference

Spring事務、異步和循環依賴的關系有哪些

getBeanPostProcessors()

而此時執行 getEarlyBeanReference 先判斷 InfrastructureAdvisorAutoProxyCreator true 調用  wrapIfNecessary 判斷是否生成一個代理對象,這里并沒有生成代理對象。

Spring事務、異步和循環依賴的關系有哪些

然后開始執行異步的 AsyncAnnotationBeanPostProcessor 判斷為 false。所以沒有執行異步的生成代理對象邏輯。

那就繼續往下看

Spring事務、異步和循環依賴的關系有哪些

到這一步還是正常的

進入到 initializeBean 的邏輯,有一部分叫做 applyBeanPostProcessorsAfterInitialization

方面小伙伴搜索,所以貼出來代碼關鍵字。IDEA 使用 ? + Shift + F 搜索。

Spring事務、異步和循環依賴的關系有哪些

applyBeanPostProcessorsAfterInitialization

循環執行后置處理器:

Spring事務、異步和循環依賴的關系有哪些

Spring事務、異步和循環依賴的關系有哪些

發現執行完 AsyncAnnotationBeanPostProcessor 這個 PostProcessor 后,對象被改變了。從而導致二級緩存和當前的  Bean 不同。

以上也就是為什么 @Async 自調用不可以,因為在后面初始化階段被代理修改了對象。

@Transactional 為什么可以呢?

Spring事務、異步和循環依賴的關系有哪些

getEarlyBeanReference

Spring事務、異步和循環依賴的關系有哪些

getBeanPostProcessors()

先判斷 InfrastructureAdvisorAutoProxyCreator true 生成一個代理對象。

Spring事務、異步和循環依賴的關系有哪些

生成代理對象

事務的處理器 PersistenceExceptionTranslationPostProcessor 也沒有執行。

繼續 Debug 關注 applyBeanPostProcessorsAfterInitialization

Spring事務、異步和循環依賴的關系有哪些

執行結束,發現 Bean 沒有發生改變。

總結

  • @Transactional: 是在循環依賴從二級緩存升到三級緩存的時候已經生成了代理對象。

  • @Async: 是在初始化階段(initializeBean)去生成代理對象。然后 @Async 導致后面判斷 exposedObject == bean  為 false ,從而拋出異常。

Spring事務、異步和循環依賴的關系有哪些

自注入

可以看出圖中有兩處會執行 BeanPostProcessor :

  1. 在 singletonFactory.getObject 時,如果是 SmartInstantiationAwareBeanPostProcessor  的子類會執行 getEarlyBeanReference 方法。

  2. 在 initializeBean 的 applyBeanPostProcessorsAfterInitialization 時會執行所有  BeanPostProcessor 的 postProcessAfterInitialization 的方法。

也有其他的地方在執行后置處理器,比如 applyBeanPostProcessorsBeforeInitialization  ,只不過這里關注這倆處。

而這兩處都有可能生成代理對象, @Transactional 是在 getEarlyBeanReference 處生成的代理對象,所以后面判斷 Bean  是否被改變時為 true,而 @Async 是在后面異步生成了代理對象,所以判斷不通過。

到此,關于“Spring事務、異步和循環依賴的關系有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

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

AI

旬阳县| 清河县| 伊吾县| 嘉鱼县| 酒泉市| 呼图壁县| 丰顺县| 诏安县| 靖边县| 阜阳市| 沽源县| 武城县| 砚山县| 东城区| 莱州市| 江陵县| 佛学| 襄汾县| 绥芬河市| 田东县| 喜德县| 万山特区| 六盘水市| 清水县| 禄丰县| 沙雅县| 盈江县| 郴州市| 平顶山市| 孝感市| 买车| 正安县| 兴城市| 玛多县| 麻城市| 南宫市| 临清市| 瓮安县| 舒城县| 武定县| 民和|