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

springboot循環(huán)依賴問題案例代碼及解決辦法

 更新時間:2025年04月03日 14:50:19   作者:學亮編程手記  
在 Spring Boot 中,如果兩個或多個 Bean之間存在循環(huán)依賴(即 Bean A 依賴 Bean B,而 Bean B 又依賴 Bean A),會導(dǎo)致 Spring 的依賴注入機制無法正確處理,從而拋出異常,下面給大家介紹springboot循環(huán)依賴問題及其解決辦法,感興趣的朋友一起看看吧

在 Spring Boot 中,如果兩個或多個 Bean 之間存在循環(huán)依賴(即 Bean A 依賴 Bean B,而 Bean B 又依賴 Bean A),會導(dǎo)致 Spring 的依賴注入機制無法正確處理,從而拋出異常。以下是循環(huán)依賴的場景分析、案例代碼及常見的解決方法。

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

概念

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

  • 直接循環(huán)依賴
    • A 依賴 B,B 依賴 A
  • 間接循環(huán)依賴
    • A 依賴 B,B 依賴 C,而 C 又依賴 A。

2. 循環(huán)依賴的場景案例

以下是一個簡單的直接循環(huán)依賴場景。

案例代碼 Bean A

@Component
public class BeanA {
    @Autowired
    private BeanB beanB;
    public BeanA() {
        System.out.println("BeanA Constructor");
    }
    public void doSomething() {
        System.out.println("BeanA is doing something");
    }
}

Bean B

@Component
public class BeanB {
    @Autowired
    private BeanA beanA;
    public BeanB() {
        System.out.println("BeanB Constructor");
    }
    public void doSomething() {
        System.out.println("BeanB is doing something");
    }
}

啟動類

@SpringBootApplication
public class CircularDependencyDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(CircularDependencyDemoApplication.class, args);
    }
}

運行結(jié)果

運行時,Spring 會拋出以下異常:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'beanA':
Requested bean is currently in creation: Is there an unresolvable circular reference?

3. 解決循環(huán)依賴的常見方法

方法 1:使用 @Lazy 注解

@Lazy 注解可以延遲加載 Bean,使 Spring 在真正需要使用時才注入依賴,從而打破循環(huán)依賴。

修改代碼

在其中一個依賴上添加 @Lazy 注解:

BeanA:

@Component
public class BeanA {
    @Autowired
    @Lazy
    private BeanB beanB;
    public BeanA() {
        System.out.println("BeanA Constructor");
    }
    public void doSomething() {
        System.out.println("BeanA is doing something");
    }
}

BeanB:

@Component
public class BeanB {
    @Autowired
    private BeanA beanA;
    public BeanB() {
        System.out.println("BeanB Constructor");
    }
    public void doSomething() {
        System.out.println("BeanB is doing something");
    }
}

運行結(jié)果

程序運行正常,輸出:

BeanA Constructor
BeanB Constructor

方法 2:使用構(gòu)造器注入解決循環(huán)依賴

Spring 無法通過構(gòu)造器注入解決循環(huán)依賴,因為在構(gòu)造器注入的過程中,所有依賴必須在實例化時完全注入。這種情況下,需要重新設(shè)計代碼結(jié)構(gòu)以打破循環(huán)依賴。

重構(gòu)代碼

將循環(huán)依賴重構(gòu)為單向依賴。例如,可以引入第三方協(xié)作者 Bean 來解耦。

BeanA:

@Component
public class BeanA {
    private final Helper helper;
    public BeanA(Helper helper) {
        this.helper = helper;
        System.out.println("BeanA Constructor");
    }
    public void doSomething() {
        System.out.println("BeanA is doing something");
    }
}

BeanB:

@Component
public class BeanB {
    private final Helper helper;
    public BeanB(Helper helper) {
        this.helper = helper;
        System.out.println("BeanB Constructor");
    }
    public void doSomething() {
        System.out.println("BeanB is doing something");
    }
}

Helper:

@Component
public class Helper {
    public void assist() {
        System.out.println("Helper is assisting");
    }
}

運行結(jié)果

Helper Constructor
BeanA Constructor
BeanB Constructor

通過引入 Helper,BeanABeanB 不再直接依賴彼此,循環(huán)依賴被消除。

方法 3:使用 @PostConstruct 或 Setter 注入

通過構(gòu)造器注入會導(dǎo)致循環(huán)依賴問題,但可以使用 Setter 方法注入來延遲依賴注入的時機。

修改代碼

BeanA:

@Component
public class BeanA {
    private BeanB beanB;
    public BeanA() {
        System.out.println("BeanA Constructor");
    }
    @Autowired
    public void setBeanB(BeanB beanB) {
        this.beanB = beanB;
    }
    public void doSomething() {
        System.out.println("BeanA is doing something");
    }
}

BeanB:

@Component
public class BeanB {
    private BeanA beanA;
    public BeanB() {
        System.out.println("BeanB Constructor");
    }
    @Autowired
    public void setBeanA(BeanA beanA) {
        this.beanA = beanA;
    }
    public void doSomething() {
        System.out.println("BeanB is doing something");
    }
}

運行結(jié)果

BeanA Constructor
BeanB Constructor

Setter 注入允許 Spring 在實例化 Bean 后再設(shè)置依賴,從而避免循環(huán)依賴問題。

方法 4:使用 ObjectFactory 或 Provider 進行延遲注入

Spring 提供了 ObjectFactoryProvider 接口,用于延遲獲取 Bean,從而避免循環(huán)依賴。

修改代碼 BeanA:

@Component
public class BeanA {
    private final ObjectFactory<BeanB> beanBFactory;
    public BeanA(ObjectFactory<BeanB> beanBFactory) {
        this.beanBFactory = beanBFactory;
        System.out.println("BeanA Constructor");
    }
    public void doSomething() {
        BeanB beanB = beanBFactory.getObject();
        System.out.println("BeanA is doing something with " + beanB);
    }
}

BeanB:

@Component
public class BeanB {
    private final BeanA beanA;
    @Autowired
    public BeanB(BeanA beanA) {
        this.beanA = beanA;
        System.out.println("BeanB Constructor");
    }
    public void doSomething() {
        System.out.println("BeanB is doing something");
    }
}

運行結(jié)果

BeanA Constructor
BeanB Constructor

通過 ObjectFactory,BeanA 可以在需要時動態(tài)獲取 BeanB,避免了循環(huán)依賴。

方法 5:使用 @DependsOn 明確加載順序

如果循環(huán)依賴是因為 Bean 的加載順序問題,可以使用 @DependsOn 指定加載順序。

修改代碼

BeanA:

@Component
@DependsOn("beanB") // 指定 BeanB 應(yīng)該先加載
public class BeanA {
    @Autowired
    private BeanB beanB;
    public BeanA() {
        System.out.println("BeanA Constructor");
    }
    public void doSomething() {
        System.out.println("BeanA is doing something");
    }
}

BeanB:

@Component
public class BeanB {
    @Autowired
    private BeanA beanA;
    public BeanB() {
        System.out.println("BeanB Constructor");
    }
    public void doSomething() {
        System.out.println("BeanB is doing something");
    }
}

運行結(jié)果

BeanB Constructor
BeanA Constructor

4. 總結(jié)

循環(huán)依賴是常見問題,但可以通過多種方式解決:

  • 使用 @Lazy 延遲加載。
  • 重構(gòu)代碼,避免直接循環(huán)依賴。
  • 使用 Setter 注入或 @PostConstruct。
  • 使用 ObjectFactory 或 Provider 進行延遲注入。
  • 使用 @DependsOn 明確加載順序。

推薦方案

如果可以重構(gòu)代碼,消除循環(huán)依賴本身是最佳實踐。在必要時,結(jié)合 @LazyObjectFactory 來解決循環(huán)依賴問題。

到此這篇關(guān)于springboot循環(huán)依賴問題及其解決辦法的文章就介紹到這了,更多相關(guān)springboot循環(huán)依賴內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談Java(SpringBoot)基于zookeeper的分布式鎖實現(xiàn)

    淺談Java(SpringBoot)基于zookeeper的分布式鎖實現(xiàn)

    這篇文章主要介紹了Java(SpringBoot)基于zookeeper的分布式鎖實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-03-03
  • iReport簡單使用方法圖文教程

    iReport簡單使用方法圖文教程

    iReport是一個能夠創(chuàng)建復(fù)雜報表的開源項目,它100%使用Java語言編寫,是目前全球最為流行的開源報表設(shè)計器,由于它豐富的圖形界面,你能夠很快的創(chuàng)建出任何一種你想要的報表
    2021-10-10
  • MyBatis流式查詢兩種實現(xiàn)方式

    MyBatis流式查詢兩種實現(xiàn)方式

    本文詳解MyBatis流式查詢,通過ResultHandler和Cursor實現(xiàn)邊讀邊處理,避免內(nèi)存溢出,ResultHandler逐條回調(diào),Cursor支持迭代,需注意事務(wù)控制及游標關(guān)閉問題,適合不同場景靈活使用,感興趣的朋友跟隨小編一起看看吧
    2025-08-08
  • MyBatis-Plus進行分頁查詢優(yōu)化的實踐指南

    MyBatis-Plus進行分頁查詢優(yōu)化的實踐指南

    在實際開發(fā)中,分頁查詢是常見的需求,尤其是需要關(guān)聯(lián)其他表獲取額外信息的場景,本文將介紹如何使用 MyBatis-Plus 進行高效分頁查詢,并結(jié)合關(guān)聯(lián)查詢優(yōu)化數(shù)據(jù)填充,需要的可以了解下
    2025-07-07
  • 詳解Java的四種引用方式及其區(qū)別

    詳解Java的四種引用方式及其區(qū)別

    這篇文章主要介紹了Java的四種引用方式 ,主要主要包括強引用,軟引用,弱引用,虛引用,稍微整理精簡一下做下分享,具有一定的參考價值,需要的朋友可以參考下
    2018-12-12
  • SpringBoot使用Sa-Token實現(xiàn)路徑攔截和特定接口放行

    SpringBoot使用Sa-Token實現(xiàn)路徑攔截和特定接口放行

    這篇文章主要介紹了SpringBoot使用Sa-Token實現(xiàn)路徑攔截和特定接口放行,文中通過代碼示例講解的非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下
    2024-06-06
  • 詳解Spring Boot 中實現(xiàn)定時任務(wù)的兩種方式

    詳解Spring Boot 中實現(xiàn)定時任務(wù)的兩種方式

    這篇文章主要介紹了Spring Boot 中實現(xiàn)定時任務(wù)的兩種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • 一文詳解Java的餓漢和懶漢設(shè)計模式

    一文詳解Java的餓漢和懶漢設(shè)計模式

    這篇文章主要為大家詳細介紹了Java設(shè)計模式中的的餓漢模式和懶漢模式,文中的示例代碼講解詳細,對我們學習Java有一定的幫助,需要的可以參考一下
    2022-12-12
  • SpringBoot整合SpringTask實現(xiàn)定時任務(wù)的流程

    SpringBoot整合SpringTask實現(xiàn)定時任務(wù)的流程

    這篇文章主要介紹了SpringBoot整合SpringTask實現(xiàn)定時任務(wù)的流程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • MyBatisPlus超詳細分析條件查詢

    MyBatisPlus超詳細分析條件查詢

    這篇文章主要介紹了MyBatisPlus條件查詢的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-08-08

最新評論

广德县| 溆浦县| 南宫市| 湘阴县| 阳泉市| 云和县| 邵武市| 伊川县| 高密市| 武宣县| 内江市| 平昌县| 宜章县| 南投县| 安庆市| 博野县| 广平县| 湖南省| 遂宁市| 萍乡市| 济南市| 西乌珠穆沁旗| 竹山县| 石家庄市| 曲麻莱县| 灵丘县| 汽车| 玉溪市| 长岭县| 堆龙德庆县| 玛纳斯县| 衡阳县| 佛坪县| 长顺县| 手游| 云浮市| 五峰| 绥阳县| 鸡泽县| 闵行区| 德阳市|