日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Spring循環(huán)依賴的“奪命連環(huán)問”,你能招架幾波?

大家好,歡迎來到Tlog4J課堂,我是Jensen。

面試官:Spring是如何解決循環(huán)依賴問題的?

候選人:Spring用了三級緩存來解決這個(gè)問題

面試官:能具體講講它的工作原理嗎?

候選人:啊這……

Spring循環(huán)依賴其實(shí)是Spring當(dāng)中非常典型的一個(gè)問題,也非常難的一道題,因?yàn)榛卮疬@個(gè)問題本身會特別繞,而且這不僅僅是一道題這么簡單,它后面會引發(fā)面試官一系列的奪命連環(huán)問。

那今天咱一起把循環(huán)依賴涉及的問題認(rèn)真梳理一遍。

Spring循環(huán)依賴奪命連環(huán)問

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

循環(huán)依賴指的是多個(gè)對象之間的依賴關(guān)系形成一個(gè)閉環(huán)。

我們都知道,如果在代碼中,把兩個(gè)或者多個(gè)Bean相互之間去持有對方的引用,就會發(fā)生循環(huán)依賴,循環(huán)依賴會導(dǎo)致注入出現(xiàn)死循環(huán),這是Spring發(fā)生循環(huán)依賴的一個(gè)原因。

二問:Spring的循環(huán)依賴有哪幾種形態(tài)?

第一種是互相依賴,也就是A依賴B,B又依賴A,它們之間形成了一個(gè)循環(huán)依賴:

第二種是三者之間的依賴,也就是A依賴B,B依賴C,C又依賴A,形成了一個(gè)循環(huán)依賴:

第三種是自我依賴,也就是說A與A之間形成的循環(huán)依賴。

現(xiàn)實(shí)中由于依賴層次深、關(guān)系復(fù)雜等因素, 導(dǎo)致循環(huán)依賴可能并不是那么一目了然。

三問:Spring設(shè)計(jì)三級緩存分別存放什么內(nèi)容?

三級緩存說白了就是三個(gè)Map容器,在框架里頭這種Map容器是隨處可見:

第一層: 初始化完備的單例bean。

/** Cache of singleton objects: bean name to bean instance. */
private final Map singletonObjects = new
ConcurrentHashMap<>(256);

第二層: 提前曝光的單例對象的Cache。

/** Cache of early singleton objects: bean name to bean instance. */
private final Map earlySingletonObjects = new
HashMap<>(16);

第三層: ObjectFactory工廠bean緩存, 存儲實(shí)例化后的bean Factory。

/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map> singletonFactories = new
HashMap<>(16);

四問:Spring這個(gè)三級緩存具體的工作原理是什么?

循環(huán)依賴主要是解決這個(gè)“死循環(huán)”沒有“出口”的問題,只要我們找到這個(gè)“出口”,循環(huán)依賴就能迎刃而解。

我們分四個(gè)步驟來說:

  • 當(dāng)我們通過getBean(A.class)去獲得A對象實(shí)例的時(shí)候,Spring會先去一級緩存里邊找,如果發(fā)現(xiàn)一級緩存沒有找到BeanA,就去創(chuàng)建這個(gè)A的實(shí)例,添加到三級緩存并暴露Bean。
  • 這時(shí)候通過@Autowired依賴注入BeanB的時(shí)候,也就是getBean(B.class)的時(shí)候,Spring發(fā)現(xiàn)B在一級緩存找不到,于是B又重復(fù)第一步A的步驟,創(chuàng)建這個(gè)B的實(shí)例,添加到三級緩存并暴露Bean。
  • B通過@Autowired依賴注入BeanA的時(shí)候,這時(shí)候發(fā)現(xiàn)三級緩存找到了A的實(shí)例,這時(shí)候A如果實(shí)現(xiàn)AOP會先創(chuàng)建動態(tài)代理對象,然后把A從三級緩存移入了二級緩存中,至此B依賴注入成功,并完成了初始化工作,隨即Spring把B從三級緩存移到了一級緩存里頭,B就完成了整個(gè)的初始化工作。
  • 最后Spring加到了A的創(chuàng)建周期,A依賴注入B也就完成了,然后繼續(xù)完成A的初始化工作,隨即把A從二級緩存移到一級緩存。

這里我們可以做一個(gè)總結(jié):

如果還是不理解,可以多看幾遍這個(gè)動圖:

一句話概括:先讓最底層對象完成初始化,通過三級緩存與二級緩存提前曝光創(chuàng)建中的Bean,讓其他Bean率先完成初始化。

五問:Spring在哪些情況下是無法解決循環(huán)依賴問題的呢?

有四種情況是無法解決的:

  1. 多實(shí)例Bean通過Setter注入。
  2. 通過構(gòu)造器注入Bean。
  3. 單例的代理Bean通過Setter注入。
  4. 設(shè)置@DependsOn注解的Bean。

寫在最后

其實(shí),很多同學(xué)回答這個(gè)問題的時(shí)候也都知道,Spring就是使用三級緩存來處理這個(gè)問題,但是回答這個(gè)問題的難點(diǎn)在于,很多同學(xué)對這個(gè)問題理解不透,所以當(dāng)你想要在短時(shí)間內(nèi)向面試官解釋清楚這個(gè)問題的時(shí)候,就會覺得有點(diǎn)條理不清。

以上這些都是從底層原理升華而來的具體問題,通?;ヂ?lián)網(wǎng)大廠面試都是按這個(gè)套路,包括說很多基礎(chǔ)知識像JVM、NIO、MQ等等這些也都是一樣的——面試官先從框架的工作原理入手,考察你對框架原理的理解,最后再找一些實(shí)際的問題,考你對這種技術(shù)棧的綜合的掌握能力,能不能解決實(shí)際的問題。

OK,回答好這個(gè)問題,關(guān)乎于你對Spring框架是否有深刻的理解,相信大家再次總結(jié)完后會有所收獲。


網(wǎng)站題目:Spring循環(huán)依賴的“奪命連環(huán)問”,你能招架幾波?
URL鏈接:http://m.5511xx.com/article/dppehgg.html