java中的循環(huán)依賴以及解決方案
什么是循環(huán)依賴
我們創(chuàng)建了兩個類,一個類A,一個類B(當然循環(huán)依賴不一定只是兩個類,可能是多個以及以上的類),在A里面引入了B,在B里面引入了A,這時候就構(gòu)成了一個循環(huán)問題,看似無止境,無盡頭
他們之間的關(guān)系如下
spring循環(huán)依賴解決方案
這些類在我們spring框架啟動的時候,會進行有序的掃描并實例化
拿A舉例:
1.實例化A
2.將a對象放入到指定的三級緩存對象
3.setName…當?shù)匠蓡T變量b的時候,發(fā)現(xiàn)B上面有@Atowired注解,就會觸發(fā)B的實例化過程
- 實例化B
- 將b對象放入到指定的三級緩存對象
- setName…當?shù)匠蓡T變量a的時候,就會去spring的三級緩存里面直接去拿
- B的實例化完成
4.拿到b的實例化對象
注意:構(gòu)造器注入構(gòu)成的循環(huán)依賴是無法解決的!只能拋出BeanCurrentlyInCreationException異常表示循環(huán)依賴,構(gòu)造函數(shù)之間發(fā)生循環(huán)依賴(A的構(gòu)造方法中依賴B,B的構(gòu)造方法中依賴A),程序會在運行時一直循環(huán)調(diào)用最終導致內(nèi)存溢出。
錯誤原因:
根本原因是 Spring 解決循環(huán)依賴依靠的是 Bean 的 中間態(tài) 這個概念,而中間態(tài)指的是 已經(jīng)實例化,但未初始化的狀態(tài)。而構(gòu)造器負責的是實例化,故無法解決構(gòu)造器循環(huán)依賴。
spring的三級緩存
在Spring框架中,有一個名為"三級緩存"(Three-level Cache)的概念,用于管理Bean的創(chuàng)建和解決循環(huán)依賴的問題。
三級緩存是指在Spring容器實例化Bean的過程中,使用了三個緩存來管理Bean的創(chuàng)建和依賴關(guān)系。具體來說,這三個緩存分別是singletonObjects、earlySingletonObjects和singletonFactories。
singletonObjects:這是一級緩存,用于保存已經(jīng)完全初始化的單例Bean的實例。當Bean創(chuàng)建完成后,它將被放入此緩存中,并且可以通過Bean名稱進行訪問。
earlySingletonObjects:這是二級緩存,用于保存已經(jīng)實例化但尚未完全初始化的單例Bean的實例。當Spring框架檢測到循環(huán)依賴時,會首先將已實例化但未初始化的Bean放入該緩存中,以便后續(xù)的依賴注入。一旦所有的依賴都已注入完成,Bean將從此緩存中移除,并放入一級緩存中。
singletonFactories:這是三級緩存,用于保存Bean的工廠類實例。當Spring框架檢測到循環(huán)依賴時,會先創(chuàng)建一個Bean的工廠類實例并放入該緩存中。這樣,當另一個Bean需要引用該Bean時,可以通過工廠類來獲取實例,并在后續(xù)的實例化過程中完成循環(huán)依賴。
通過使用這三個級別的緩存,Spring框架可以在解決循環(huán)依賴問題時進行適當?shù)奶幚恚_保Bean的實例化和依賴注入的順序正確。同時,三級緩存也有助于提高性能,避免重復創(chuàng)建Bean實例。但需要注意的是,三級緩存是Spring框架內(nèi)部使用的機制,對開發(fā)者來說通常是透明的,不需要直接操作或干預。
在Java中,使用三級緩存是解決循環(huán)依賴問題的一種方案,通常被稱為"提前暴露引用(Early Reference)"方案。
循環(huán)依賴是指兩個或多個Bean之間相互依賴的情況,在實例化過程中可能會造成死鎖或無法正確注入依賴的問題。為了解決這個問題,Spring框架引入了三級緩存機制,并且使用"提前暴露引用"的方式來處理循環(huán)依賴。
"提前暴露引用"方案的基本思想是,在實例化Bean的過程中,先創(chuàng)建一個早期的、未完全初始化的Bean實例,并將其放入二級緩存中。然后,在完成當前Bean的依賴注入之后,再從二級緩存中取出該早期實例并進行初始化。這樣,可以通過提前暴露引用的方式解決循環(huán)依賴的問題。
在三級緩存中的三個級別,二級緩存即為保存早期實例的緩存,通過它來實現(xiàn)"提前暴露引用"的方案。當依賴注入完成后,早期實例會轉(zhuǎn)移到一級緩存中,而三級緩存中的工廠類實例則會被移除。文章來源:http://www.zghlxwxcb.cn/news/detail-445941.html
需要注意的是,三級緩存和"提前暴露引用"方案都是Spring框架內(nèi)部實現(xiàn)的,對于開發(fā)者來說通常是透明的。開發(fā)者只需按照正常的依賴關(guān)系進行編碼,Spring框架會根據(jù)三級緩存機制來解決循環(huán)依賴問題。文章來源地址http://www.zghlxwxcb.cn/news/detail-445941.html
到了這里,關(guān)于java中的循環(huán)依賴以及解決方案的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!