最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring循環(huán)依賴??的解決方式詳解

 更新時(shí)間:2025年05月10日 11:48:48   作者:二進(jìn)制11  
這篇文章主要介紹了Spring循環(huán)依賴??的解決方式,??循環(huán)依賴??是指兩個(gè)或多個(gè)Bean互相依賴,形成閉環(huán),導(dǎo)致Spring無法正常完成依賴注入,需要的朋友可以參考下

什么是循環(huán)依賴

循環(huán)依賴是指兩個(gè)或多個(gè)Bean相互依賴,形成一個(gè)閉環(huán)。例如:

@Component
public class A {
    @Autowired
    private B b;
}
@Component
public class B {
    @Autowired
    private A a;
}

在這個(gè)例子中,A依賴B,B又依賴A,形成了一個(gè)循環(huán)依賴鏈。

Spring解決循環(huán)依賴的機(jī)制

Spring通過三級(jí)緩存機(jī)制來解決循環(huán)依賴問題,具體實(shí)現(xiàn)如下:

三級(jí)緩存結(jié)構(gòu)

  • 一級(jí)緩存(singletonObjects):存儲(chǔ)完全初始化好的Bean
  • 二級(jí)緩存(earlySingletonObjects):存儲(chǔ)提前暴露的原始Bean(尚未填充屬性)
  • 三級(jí)緩存(singletonFactories):存儲(chǔ)Bean工廠,用于生成原始Bean的早期引用

解決流程

Spring解決循環(huán)依賴的核心流程如下:

詳細(xì)步驟解析

創(chuàng)建Bean A:

  • Spring容器開始創(chuàng)建Bean A
  • 實(shí)例化A(調(diào)用構(gòu)造方法)
  • 將A的ObjectFactory放入三級(jí)緩存(singletonFactories)
  • 準(zhǔn)備填充A的屬性

發(fā)現(xiàn)依賴B:

  • 在填充A的屬性時(shí),發(fā)現(xiàn)需要注入Bean B
  • 容器開始創(chuàng)建Bean B

創(chuàng)建Bean B:

  • 實(shí)例化B(調(diào)用構(gòu)造方法)
  • 將B的ObjectFactory放入三級(jí)緩存(singletonFactories)
  • 準(zhǔn)備填充B的屬性

發(fā)現(xiàn)依賴A:

  • 在填充B的屬性時(shí),發(fā)現(xiàn)需要注入Bean A
  • 容器嘗試從一級(jí)緩存獲取A(未找到)
  • 從二級(jí)緩存獲取A(未找到)
  • 從三級(jí)緩存獲取A的ObjectFactory并調(diào)用getObject()獲取早期引用
  • 將A的早期引用放入二級(jí)緩存,并從三級(jí)緩存移除

完成B的創(chuàng)建:

  • 將B的屬性填充完整
  • 執(zhí)行B的初始化后處理器
  • 將完整的B放入一級(jí)緩存
  • 從二級(jí)和三級(jí)緩存中移除B的相關(guān)條目

完成A的創(chuàng)建:

  • 現(xiàn)在A可以獲取到完整的B實(shí)例
  • 將A的屬性填充完整
  • 執(zhí)行A的初始化后處理器
  • 將完整的A放入一級(jí)緩存
  • 從二級(jí)緩存中移除A

代碼層面的實(shí)現(xiàn)

Spring解決循環(huán)依賴的核心代碼在DefaultSingletonBeanRegistry類中:

protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 首先檢查一級(jí)緩存
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
        synchronized (this.singletonObjects) {
            // 檢查二級(jí)緩存
            singletonObject = this.earlySingletonObjects.get(beanName);
            if (singletonObject == null && allowEarlyReference) {
                // 檢查三級(jí)緩存
                ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    // 從三級(jí)緩存移到二級(jí)緩存
                    this.earlySingletonObjects.put(beanName, singletonObject);
                    this.singletonFactories.remove(beanName);
                }
            }
        }
    }
    return singletonObject;
}

循環(huán)依賴的限制

Spring并非能解決所有類型的循環(huán)依賴,有以下限制:

構(gòu)造器注入:無法解決構(gòu)造器注入的循環(huán)依賴

@Component
public class A {
    private B b;
    @Autowired
    public A(B b) { this.b = b; }
}
@Component
public class B {
    private A a;
    @Autowired
    public B(A a) { this.a = a; }
}

這種情況會(huì)拋出BeanCurrentlyInCreationException

原型(prototype)作用域的Bean:Spring不支持原型Bean的循環(huán)依賴

@Async方法:如果循環(huán)依賴中包含@Async方法,也可能出現(xiàn)問題

最佳實(shí)踐

  • 盡量避免循環(huán)依賴,設(shè)計(jì)時(shí)應(yīng)考慮解耦
  • 如果必須使用循環(huán)依賴,優(yōu)先使用setter注入而非構(gòu)造器注入
  • 考慮使用@Lazy注解延遲加載其中一個(gè)Bean
@Component
public class A {
    @Lazy
    @Autowired
    private B b;
}

總結(jié)

Spring通過三級(jí)緩存機(jī)制巧妙地解決了setter/field注入方式的循環(huán)依賴問題。理解這一機(jī)制不僅有助于我們避免開發(fā)中的循環(huán)依賴陷阱,也能更深入地理解Spring容器的Bean生命周期管理。在實(shí)際開發(fā)中,我們應(yīng)當(dāng)合理設(shè)計(jì)Bean之間的依賴關(guān)系,盡量避免循環(huán)依賴,當(dāng)確實(shí)需要時(shí),也要了解其背后的原理和限制。

以上就是Spring循環(huán)依賴??的解決方式詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring循環(huán)依賴的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

鄂托克前旗| 武汉市| 阿尔山市| 彰武县| 凯里市| 天气| 巴林左旗| 彭阳县| 敖汉旗| 莎车县| 海阳市| 五寨县| 化德县| 毕节市| 德阳市| 营山县| 桃江县| 浏阳市| 莱芜市| 五常市| 大名县| 龙口市| 吐鲁番市| 罗城| 康乐县| 德保县| 如皋市| 江城| 咸阳市| 象州县| 阿克陶县| 张掖市| 洪雅县| 富蕴县| 樟树市| 琼海市| 万山特区| 襄樊市| 徐水县| 逊克县| 伽师县|