最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring循環(huán)依賴的解決方法詳解

 更新時(shí)間:2022年08月16日 08:55:19   作者:飄飄~  
Spring的解決循環(huán)依賴是有前置條件的,要解決循環(huán)依賴我們首先要了解Spring Bean對(duì)象的創(chuàng)建過程和依賴注入的方式。依賴注入方式,我之前的博客有所分享,大家可以在看本篇文章之前進(jìn)行一下小小的回顧

說明:spring如何解決循環(huán)依賴,是面試中經(jīng)常問到的題目,今天我們就來分享一下spring是如何解決循環(huán)依賴問題的。

什么是循環(huán)依賴:

我們先來看看官方文檔的說法:

通俗來講,就是A依賴B或者B依賴A,或者C依賴自己本身,或是三個(gè)以上,例如A依賴B,B依賴C,C又依賴A。如下圖:

Spring實(shí)例Bean的本質(zhì)

Spring在實(shí)例化一個(gè)bean的時(shí)候,是首先遞歸的實(shí)例化其所依賴的所有bean,直到某個(gè)bean沒有依賴其他bean,此時(shí)就會(huì)將該實(shí)例返回,然后反遞歸的將獲取到的bean設(shè)置為各個(gè)上層bean的屬性的。

循環(huán)依賴主要場(chǎng)景

什么情況下循環(huán)依賴可以被解決

Spring解決循環(huán)依賴是有前置條件的

  • 出現(xiàn)循環(huán)依賴的Bean必須要是單例(singleton),如果依賴prototype則完全不會(huì)有此需求。
  • 依賴注入的方式不能全是構(gòu)造器注入的方式。

解決方式

Spring是通過三級(jí)緩存來解決上述問題的:

一級(jí)緩存: singletonObjects存儲(chǔ)的是所有創(chuàng)建好了的單例Bean

二級(jí)緩存:earlySingletonObjects完成實(shí)例化,但是還未進(jìn)行屬性注入及初始化的對(duì)象

三級(jí)緩存:singletonFactories提前暴露的一個(gè)單例工廠,二級(jí)緩存中存儲(chǔ)的就是從這個(gè)工廠中獲取到的對(duì)象。

三級(jí)緩存解決循環(huán)依賴流程:

  1. 獲取A時(shí)首先會(huì)嘗試從一級(jí)緩存singletonObjects中獲?。?/li>
  2. 獲取不到就再從二級(jí)緩存earlySingletonObjects中獲?。?/li>
  3. 若是還沒有則嘗試從三級(jí)緩存singletonFactories獲??;
  4. 還是沒有獲取到則再嘗試創(chuàng)建A對(duì)象
  5. 會(huì)執(zhí)行doGetBean->createBean->createBeanInstance并使用構(gòu)造器實(shí)例化
  6. 在嘗試給A進(jìn)行初始化時(shí),由于B不存在無法完成初始化,則將半成品A放入第二級(jí)緩存中,進(jìn)入B的創(chuàng)建流程。
  7. 與先前過程相似,在第三級(jí)緩存中放入beanName和表達(dá)式sharedInstance,進(jìn)入B的初始化過程
  8. 由于在第二級(jí)緩存中可以找到A,則B可以完成初始化,將成品Bean放入一級(jí)緩存中備用,刪除三級(jí)緩存中的B
  9. 同時(shí)完成A的初始化,并刪除二級(jí)緩存中的半成品A

具體流程圖如下:

最后我們來個(gè)小小的總結(jié):

Spring通過三級(jí)緩存解決了循環(huán)依賴,其中一級(jí)緩存為單例池(singletonObjects),二級(jí)緩存為早期曝光對(duì)象earlySingletonObjects,三級(jí)緩存為早期曝光對(duì)象工廠(singletonFactories)。

當(dāng)A、B兩個(gè)類發(fā)生循環(huán)引用時(shí),在A完成實(shí)例化后,就使用實(shí)例化后的對(duì)象去創(chuàng)建一個(gè)對(duì)象工廠,添加到三級(jí)緩存中,如果A被AOP代理,那么通過這個(gè)工廠獲取到的就是A代理后的對(duì)象,如果A沒有被AOP代理,那么這個(gè)工廠獲取到的就是A實(shí)例化的對(duì)象。

當(dāng)A進(jìn)行屬性注入時(shí),會(huì)去創(chuàng)建B,同時(shí)B又依賴了A,所以創(chuàng)建B的同時(shí)又會(huì)去調(diào)用getBean(a)來獲取需要的依賴,此時(shí)的getBean(a)會(huì)從緩存中獲取。

  • 先獲取到三級(jí)緩存中的工廠;
  • 調(diào)用對(duì)象工工廠的getObject方法來獲取到對(duì)應(yīng)的對(duì)象,得到這個(gè)對(duì)象后將其注入到B中。緊接著B會(huì)走完它的生命周期流程,包括初始化、后置處理器等。
  • 當(dāng)B創(chuàng)建完后,會(huì)將B再注入到A中,此時(shí)A再完成它的整個(gè)生命周期。至此,循環(huán)依賴結(jié)束!

到此這篇關(guān)于Spring循環(huán)依賴的解決方法詳解的文章就介紹到這了,更多相關(guān)Spring循環(huán)依賴內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot郵箱鏈接注冊(cè)驗(yàn)證及注冊(cè)流程

    Spring Boot郵箱鏈接注冊(cè)驗(yàn)證及注冊(cè)流程

    這篇文章給大家介紹Spring Boot郵箱鏈接注冊(cè)驗(yàn)證問題及注冊(cè)流程分析,通過實(shí)例代碼給大家分享實(shí)現(xiàn)過程,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • 教你一步到位部署運(yùn)行MyBatis3源碼(保姆級(jí))

    教你一步到位部署運(yùn)行MyBatis3源碼(保姆級(jí))

    一個(gè)框架的運(yùn)行流程從最簡(jiǎn)單的一個(gè)helloworld來看其源碼就能了解到框架的原理是什么,這篇文章主要給大家介紹了關(guān)于如何一步到位部署運(yùn)行MyBatis3源碼的相關(guān)資料,需要的朋友可以參考下
    2022-06-06
  • Java編程異常簡(jiǎn)單代碼示例

    Java編程異常簡(jiǎn)單代碼示例

    這篇文章主要介紹了Java編程異常簡(jiǎn)單代碼示例,還是比較不錯(cuò)的,這里分享個(gè)大家,需要的朋友可以參考下。
    2017-11-11
  • Mybatis-plus更新字段為null兩種常用方法及優(yōu)化

    Mybatis-plus更新字段為null兩種常用方法及優(yōu)化

    Mybatis Plus在進(jìn)行更新操作時(shí),默認(rèn)情況下是不能將字段更新為null的,如果要更新字段為null,需要進(jìn)行以下處理,這篇文章主要給大家介紹了關(guān)于Mybatis-plus更新字段為null的兩種常用方法及優(yōu)化,需要的朋友可以參考下
    2024-03-03
  • Java操作redis實(shí)現(xiàn)增刪查改功能的方法示例

    Java操作redis實(shí)現(xiàn)增刪查改功能的方法示例

    這篇文章主要介紹了Java操作redis實(shí)現(xiàn)增刪查改功能的方法,涉及java操作redis數(shù)據(jù)庫的連接、設(shè)置、增刪改查、釋放資源等相關(guān)操作技巧,需要的朋友可以參考下
    2017-08-08
  • SpringBoot預(yù)加載與懶加載實(shí)現(xiàn)方法超詳細(xì)講解

    SpringBoot預(yù)加載與懶加載實(shí)現(xiàn)方法超詳細(xì)講解

    Spring一直被詬病啟動(dòng)時(shí)間慢,可Spring/SpringBoot是輕量級(jí)的框架。因?yàn)楫?dāng)Spring項(xiàng)目越來越大的時(shí)候,在啟動(dòng)時(shí)加載和初始化Bean就會(huì)變得越來越慢,很多時(shí)候我們?cè)趩?dòng)時(shí)并不需要加載全部的Bean,在調(diào)用時(shí)再加載就行,那這就需要預(yù)加載與懶加載的功能了
    2022-11-11
  • 超級(jí)詳細(xì)的Java安裝教程(Mac版)

    超級(jí)詳細(xì)的Java安裝教程(Mac版)

    Java是一種廣泛使用的編程語言,可用于開發(fā)各種類型的應(yīng)用程序,這篇文章主要給大家介紹了關(guān)于Mac系統(tǒng)下Java安裝的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-10-10
  • Java算法設(shè)計(jì)與分析分治算法

    Java算法設(shè)計(jì)與分析分治算法

    這篇文章主要介紹了Java算法設(shè)計(jì)與分析分治算法,一般分治算法在正文中分解為兩個(gè)即以上的遞歸調(diào)用,并且子類問題一般是不想交的
    2022-07-07
  • 30分鐘入門Java8之lambda表達(dá)式學(xué)習(xí)

    30分鐘入門Java8之lambda表達(dá)式學(xué)習(xí)

    本篇文章主要介紹了30分鐘入門Java8之lambda表達(dá)式學(xué)習(xí),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-04-04
  • Mybatis攔截器實(shí)現(xiàn)一種百萬級(jí)輕量分表方案

    Mybatis攔截器實(shí)現(xiàn)一種百萬級(jí)輕量分表方案

    這篇文章主要介紹了Mybatis攔截器實(shí)現(xiàn)一種百萬級(jí)輕量分表方案,需要的朋友可以參考下
    2024-02-02

最新評(píng)論

吕梁市| 美姑县| 邢台县| 宁乡县| 同仁县| 晋城| 洪洞县| 莆田市| 南汇区| 明光市| 永吉县| 陈巴尔虎旗| 普兰店市| 正阳县| 东辽县| 长海县| 乌鲁木齐市| 盐山县| 色达县| 武宁县| 丽水市| 基隆市| 梅州市| 郑州市| 上蔡县| 凤山市| 济宁市| 洛宁县| 特克斯县| 昭觉县| 全椒县| 宣威市| 林甸县| 晋宁县| 抚顺县| 彩票| 淄博市| 页游| 清远市| 大同县| 会同县|