亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

概念

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

  • 直接循環(huán)依賴
    • A 依賴 B,B 依賴 A。
  • 間接循環(huán)依賴
    • A 依賴 BB 依賴 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);
    }
}

運行結果

運行時,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");
    }
}

運行結果

程序運行正常,輸出:

BeanA Constructor
BeanB Constructor

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

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

重構代碼

將循環(huán)依賴重構為單向依賴。例如,可以引入第三方協(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");
    }
}

運行結果

Helper Constructor
BeanA Constructor
BeanB Constructor

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

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

通過構造器注入會導致循環(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");
    }
}

運行結果

BeanA Constructor
BeanB Constructor

Setter 注入允許 Spring 在實例化 Bean 后再設置依賴,從而避免循環(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");
    }
}

運行結果

BeanA Constructor
BeanB Constructor

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

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

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

修改代碼

BeanA:

@Component
@DependsOn("beanB") // 指定 BeanB 應該先加載
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");
    }
}

運行結果

BeanB Constructor
BeanA Constructor

4. 總結

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

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

推薦方案

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

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

相關文章

  • spring?@Scheduled注解各參數使用以及定時任務詳解

    spring?@Scheduled注解各參數使用以及定時任務詳解

    文章詳細介紹了Spring框架中@Scheduled注解的各個參數,包括cron表達式、時區(qū)、fixedDelay、fixedRate、initialDelay等,并提供了多個示例來說明這些參數的使用方法
    2024-11-11
  • Spring Event觀察者模式事件監(jiān)聽詳解

    Spring Event觀察者模式事件監(jiān)聽詳解

    這篇文章主要介紹了Java Spring Event事件監(jiān)聽詳情解析,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • Java遞歸遍歷文件目錄代碼實例

    Java遞歸遍歷文件目錄代碼實例

    這篇文章主要介紹了Java遞歸遍歷文件目錄代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-11-11
  • Java躲不過設計模式的坑之代理模式詳解

    Java躲不過設計模式的坑之代理模式詳解

    設計模式看來更像是一種設計思維或設計思想,為你的項目工程提供方向,讓你的項目工程更加健壯、靈活,延續(xù)生命力。本文即將分享的是設計模式的其中一種:代理模式,感興趣的可以了解一下
    2022-09-09
  • java之jvm加載器例舉

    java之jvm加載器例舉

    在本篇文章里小編給大家介紹了關于java之jvm加載器例舉內容,對此有需要的程序員朋友們可以參考下。
    2021-03-03
  • 解決@Async(“taskExecutor“)異步線程報錯問題

    解決@Async(“taskExecutor“)異步線程報錯問題

    這篇文章主要介紹了解決@Async(“taskExecutor“)異步線程報錯問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Spring Junit單元測試加載配置文件失敗問題

    Spring Junit單元測試加載配置文件失敗問題

    這篇文章主要介紹了Spring Junit加載配置文件失敗問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-05-05
  • Java實現簡易生產者消費者模型過程解析

    Java實現簡易生產者消費者模型過程解析

    這篇文章主要介紹了Java實現簡易生產者消費者模型過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-06-06
  • springmvc 中dao層和service層的區(qū)別說明

    springmvc 中dao層和service層的區(qū)別說明

    這篇文章主要介紹了springmvc 中dao層和service層的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java執(zhí)行shell并獲取shell輸出日志方式

    java執(zhí)行shell并獲取shell輸出日志方式

    這篇文章主要介紹了java執(zhí)行shell并獲取shell輸出日志方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04

最新評論