- Spring Boot進(jìn)階:原理、實(shí)戰(zhàn)與面試題分析
- 鄭天民
- 529字
- 2022-07-05 09:41:43
2.3.2 循環(huán)依賴解決方案
讓我們回顧2.1.3節(jié)中基于Setter方法注入的循環(huán)依賴場景,如代碼清單2-21所示。
代碼清單2-21 基于Setter方法注入的循環(huán)依賴代碼
public class ClassA { private ClassB classB; @Autowired public void setClassB(ClassB classB) { this.classB = classB; } } public class ClassB { private ClassA classA; @Autowired public void setClassA(ClassA classA) { this.classA = classA; } }
現(xiàn)在假設(shè)我們先初始化ClassA。ClassA首先通過createBeanInstance()方法創(chuàng)建了實(shí)例,并且將這個實(shí)例提前暴露到第三級緩存singletonFactories中。然后,ClassA嘗試通過populateBean()方法注入屬性,發(fā)現(xiàn)自己依賴ClassB這個屬性,就會嘗試去獲取ClassB的實(shí)例。
顯然,這時候ClassB還沒有被創(chuàng)建,所以要走創(chuàng)建流程。ClassB在初始化第一步的時候發(fā)現(xiàn)自己依賴了ClassA,就會嘗試從第一級緩存singletonObjects去獲取ClassA的實(shí)例。因?yàn)镃lassA這時候還沒有被創(chuàng)建完畢,所以它在第一級緩存和第二級緩存中都不存在。當(dāng)嘗試訪問第三級緩存時,因?yàn)镃lassA已經(jīng)提前暴露了,所以ClassB能夠通過singletonFactories拿到ClassA對象并順利完成所有初始化流程。
ClassB對象創(chuàng)建完成之后會被放到第一級緩存中,這時候ClassA就能從第一級緩存中獲取ClassB的實(shí)例,進(jìn)而完成ClassA的所有初始化流程。這樣ClassA和ClassB都能夠成功完成創(chuàng)建過程,整個流程如圖2-3所示。

圖2-3 基于Setter方法注入的循環(huán)依賴解決流程
講到這里,相信你也理解了為什么構(gòu)造器注入無法解決循環(huán)依賴問題。這是因?yàn)闃?gòu)造器注入過程是發(fā)生在Bean初始化的第一個步驟createBeanInstance()中,而這個步驟還沒有調(diào)用addSingletonFactory()方法完成第三級緩存的構(gòu)建,自然也就無法從該緩存中獲取目標(biāo)對象。
- JavaScript:Functional Programming for JavaScript Developers
- C#完全自學(xué)教程
- Getting Started with PowerShell
- Java程序員面試算法寶典
- App Inventor 2 Essentials
- C語言從入門到精通
- Python編程基礎(chǔ)教程
- 網(wǎng)頁設(shè)計與制作
- ASP.NET本質(zhì)論
- Improving your Penetration Testing Skills
- GO語言編程從入門到實(shí)踐
- PhoneGap 3.x Mobile Application Development Hotshot
- 像程序員一樣使用MySQL
- The Python Apprentice
- Performance Testing with JMeter 3(Third Edition)