欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

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

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

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

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

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

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

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

解決流程

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

詳細(xì)步驟解析

創(chuàng)建Bean A:

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

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

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

創(chuàng)建Bean B:

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

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

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

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

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

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

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

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

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

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

這種情況會拋出BeanCurrentlyInCreationException

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

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

最佳實(shí)踐

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

總結(jié)

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

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

相關(guān)文章

  • JAVA中整型數(shù)組、字符串?dāng)?shù)組、整型數(shù)和字符串 的創(chuàng)建與轉(zhuǎn)換的方法

    JAVA中整型數(shù)組、字符串?dāng)?shù)組、整型數(shù)和字符串 的創(chuàng)建與轉(zhuǎn)換的方法

    本文介紹了Java中字符串、字符數(shù)組和整型數(shù)組的創(chuàng)建方法,以及它們之間的轉(zhuǎn)換方法,還詳細(xì)講解了字符串中的一些常用方法,如indexOf()方法,并通過一個算法題目來應(yīng)用這些知識,感興趣的朋友一起看看吧
    2025-01-01
  • Spring源碼解密之默認(rèn)標(biāo)簽的解析

    Spring源碼解密之默認(rèn)標(biāo)簽的解析

    這篇文章主要給大家介紹了關(guān)于Spring源碼解密之默認(rèn)標(biāo)簽的解析的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • java中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析

    java中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析

    這篇文章主要介紹了java中struts2實(shí)現(xiàn)文件上傳下載功能的方法,以實(shí)例形式較為詳細(xì)的分析了struts2實(shí)現(xiàn)文件上傳下載功能的具體實(shí)現(xiàn)技巧與相關(guān)問題的解決方法,具有一定的參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • Java 中HashCode作用_動力節(jié)點(diǎn)Java學(xué)院整理

    Java 中HashCode作用_動力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了Java 中HashCode作用以及hashcode對于一個對象的重要性,對java中hashcode的作用相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2017-05-05
  • JVM的垃圾回收算法一起來看看

    JVM的垃圾回收算法一起來看看

    這篇文章主要為大家詳細(xì)介紹了JVM的垃圾回收算法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • springBoot集成flowable的流程解析

    springBoot集成flowable的流程解析

    這篇文章主要介紹了springBoot集成flowable的流程,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02
  • JavaWeb開發(fā)基于ssm的校園服務(wù)系統(tǒng)(實(shí)例詳解)

    JavaWeb開發(fā)基于ssm的校園服務(wù)系統(tǒng)(實(shí)例詳解)

    這篇文章主要介紹了JavaWeb開發(fā)基于ssm的校園服務(wù)系統(tǒng),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-02-02
  • netty服務(wù)端輔助類ServerBootstrap創(chuàng)建邏輯分析

    netty服務(wù)端輔助類ServerBootstrap創(chuàng)建邏輯分析

    這篇文章主要介紹了netty服務(wù)端輔助類ServerBootstrap創(chuàng)建邏輯分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • springboot如何添加全局異常捕獲類

    springboot如何添加全局異常捕獲類

    這篇文章主要介紹了springboot如何添加全局異常捕獲類,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • Spring外部化配置的幾種技巧分享

    Spring外部化配置的幾種技巧分享

    在油管上看了龍之春的一個Spring tips 視頻,講述Spring外部化配置的幾種技巧,收獲頗多,想拿出來給大家分享下。對spring感興趣的朋友可以了解下本文
    2021-06-06

最新評論