自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Spring循環(huán)依賴的“奪命連環(huán)問”,你能招架幾波?

開發(fā) 前端
Spring循環(huán)依賴其實是Spring當中非常典型的一個問題,也非常難的一道題,因為回答這個問題本身會特別繞,而且這不僅僅是一道題這么簡單,它后面會引發(fā)面試官一系列的奪命連環(huán)問。

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

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

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

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

候選人:啊這……

Spring循環(huán)依賴其實是Spring當中非常典型的一個問題,也非常難的一道題,因為回答這個問題本身會特別繞,而且這不僅僅是一道題這么簡單,它后面會引發(fā)面試官一系列的奪命連環(huán)問。

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

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

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

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

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

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

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

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

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

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

三問:Spring設計三級緩存分別存放什么內容?

三級緩存說白了就是三個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緩存, 存儲實例化后的bean Factory。

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

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

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

我們分四個步驟來說:

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

這里我們可以做一個總結:

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

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

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

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

  1. 多實例Bean通過Setter注入。
  2. 通過構造器注入Bean。
  3. 單例的代理Bean通過Setter注入。
  4. 設置@DependsOn注解的Bean。

寫在最后

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

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

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

責任編輯:姜華 來源: 今日頭條
相關推薦

2023-03-08 09:03:55

2021-10-26 15:56:57

kafka數(shù)據(jù)平臺,

2023-02-26 02:00:36

OpenFeign接口實現(xiàn)類

2024-03-13 13:56:11

openFeignHttp服務調用

2023-04-26 09:16:17

2022-04-01 12:40:13

MySQL數(shù)據(jù)庫

2022-01-24 14:08:16

Redis面試命令

2021-06-04 14:38:12

網(wǎng)絡通信TCP揮手

2021-11-08 14:10:37

分布式Spring鏈路

2021-01-19 05:24:36

ThreadLocal線程編程

2019-05-29 15:17:43

TCPHTTPSSL

2022-05-14 21:19:22

ThreadLocaJDKsynchroniz

2021-07-21 09:15:27

MySQL數(shù)據(jù)庫面試

2021-04-26 17:58:41

MySQLIO

2023-05-04 08:06:27

Spring循環(huán)依賴

2012-04-23 13:54:12

用戶體驗

2015-11-18 09:30:13

中國IDC圈

2015-11-17 18:02:33

數(shù)據(jù)中心峰值

2025-03-17 00:21:00

2019-11-26 14:30:20

Spring循環(huán)依賴Java
點贊
收藏

51CTO技術棧公眾號