Spring為何需要三級快取解決迴圈依賴,而不是二級快取?

語言: CN / TW / HK

今天給大家分享一道大廠面試真題,Spring為何需要三級快取解決迴圈依賴,而不是二級快取?我一共分為五個部分來給大家介紹:

1、什麼是迴圈依賴?

迴圈依賴就是指迴圈引用,是兩個或多個Bean相互之間的持有對方的引用。在程式碼中,如果將兩個或多個Bean互相之間持有對方的引用,因為Spring中加入了依賴注入機制,也就是自動給屬性賦值。Spring給屬性賦值時,將會導致死迴圈。那麼,哪些情況會出現迴圈依賴呢?  

2、哪些情況會出現迴圈依賴?

迴圈依賴有三種形態:

1、相互依賴,也就是A 依賴 B,B 又依賴 A,它們之間形成了迴圈依賴。

2、三者間依賴,也就是A 依賴 B,B 依賴 C,C 又依賴 A,形成了迴圈依賴。

3、自我依賴,也是A依賴A形成了迴圈依賴自己依賴自己。 

 

3、Spring如何解決迴圈依賴問題?

Spring中設計了三級快取來解決迴圈依賴問題,當我們去呼叫getBean()方法的時候,Spring會先從一級快取中去找到目標Bean,如果發現一級快取中沒有 便會去二級快取中去找,而如果一、二級快取中都沒有找到,意味著該目標Bean還沒有例項化。於是,Spring容器會例項化目標Bean(PS:剛初始化的Bean稱為早期Bean),然後,將目標Bean放入到二級快取中,同時,加上標記是否存在迴圈依賴。如果不存在迴圈依賴便會將目標Bean存入到二級快取,否則,便會標記該Bean存在迴圈依賴,然後將等待下一次輪詢賦值,也就是解析@Autowired註解。等@Autowired註解賦值完成後(PS:完成賦值的Bean稱為成熟Bean),會將目標Bean存入到一級快取。

總結一下,Spring一級快取中存放所有的成熟Bean,二級快取中存放所有的早期Bean,先取一級快取,再去二級快取。

4、為何需要三級快取,而不是二級快取?

那麼,前面有提到三級快取,三級快取的作用是啥呢?來看這樣一張圖,三級快取是用來儲存代理Bean,當呼叫getBean()方法時,發現目標Bean需要通過代理工廠來建立,此時會將建立好的例項儲存到三級快取,最終也會將賦值好的Bean同步到一級快取中。大家可以私信我或者在評論區留言獲取高清大圖。

 

5、Spring中哪些情況下,不能解決迴圈依賴問題?

1.多例Bean通過setter注入的情況,不能解決迴圈依賴問題

2.構造器注入的Bean的情況,不能解決迴圈依賴問題

3.單例的代理Bean通過Setter注入的情況,不能解決迴圈依賴問題

4.設定了@DependsOn的Bean的情況,不能解決迴圈依賴問題

我是被程式設計耽誤的文藝Tom,如果大家還有其他疑問,請在評論區留言。如果本次面試對你有幫助,請動動手指一鍵三連分享給更多的人。關注我,面試不再難!

本文為“Tom彈架構”原創,轉載請註明出處。技術在於分享,我分享我快樂!\ 如果本文對您有幫助,歡迎關注和點贊;如果您有任何建議也可留言評論或私信,您的支援是我堅持創作的動力。

關注微信公眾號『 Tom彈架構 』可獲取更多技術乾貨!往期影片已經整理成文件形式,需要的小夥伴點個關注,搜尋下方名片!我是被程式設計耽誤的文藝Tom,

什麼條件下會產出死鎖,如何避免死鎖?