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

SpringBoot中循環(huán)依賴問題的原理與解決方案

 更新時間:2025年07月06日 08:53:15   作者:碼農(nóng)阿豪@新空間  
在Spring Boot開發(fā)中,依賴注入(DI)是核心特性之一,本文將通過一個實際錯誤案例,深入分析Spring Boot循環(huán)依賴的成因、解決方案,并提供最佳實踐建議,希望對大家有所幫助

引言

在Spring Boot開發(fā)中,依賴注入(DI)是核心特性之一,它幫助我們構(gòu)建松耦合、可測試的應(yīng)用程序。然而,當(dāng)多個Bean相互依賴時,可能會形成循環(huán)依賴(Circular Dependency),導(dǎo)致應(yīng)用啟動失敗。

本文將通過一個實際錯誤案例,深入分析Spring Boot循環(huán)依賴的成因、解決方案,并提供最佳實踐建議,幫助開發(fā)者避免此類問題。

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

1.1 循環(huán)依賴的定義

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

  • ServiceA 依賴 ServiceB
  • ServiceB 依賴 ServiceC
  • ServiceC 又依賴 ServiceA

這樣就會形成一個循環(huán)鏈,Spring在初始化時無法決定哪個Bean應(yīng)該先創(chuàng)建。

1.2 Spring Boot的默認(rèn)行為

在Spring Boot 2.6+版本中,循環(huán)依賴默認(rèn)被禁止,如果檢測到循環(huán)依賴,會拋出如下錯誤:

APPLICATION FAILED TO START
*
Description:
The dependencies of some of the beans in the application context form a cycle:
...
Action:
Relying upon circular references is discouraged and they are prohibited by default.

2. 案例分析:循環(huán)依賴的錯誤日志

以下是本文討論的錯誤日志:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.

*
APPLICATION FAILED TO START
*

Description:
The dependencies of some of the beans in the application context form a cycle:

   afterTestController → AfterTestService → OpmMediaFlowControlService → OpmOperateTeamService → SysChannelCompanyService → OpmChannelAccountService → SysChannelCompanyService

依賴鏈分析:

  • AfterTestController 依賴 AfterTestService
  • AfterTestService 依賴 OpmMediaFlowControlService
  • OpmMediaFlowControlService 依賴 OpmOperateTeamService
  • OpmOperateTeamService 依賴 SysChannelCompanyService
  • SysChannelCompanyService 依賴 OpmChannelAccountService
  • OpmChannelAccountService 又依賴 SysChannelCompanyService(形成閉環(huán))

3. 解決方案

3.1 方案1:重構(gòu)代碼(推薦)

最佳實踐是避免循環(huán)依賴,通常可以通過以下方式重構(gòu):

(1) 提取公共邏輯到新Service

如果兩個Service需要互相調(diào)用,可以將公共邏輯提取到第三個Service:

@Service
public class CommonService {
    // 公共方法
}
(2) 使用接口或事件驅(qū)動模式

接口分離:讓Service依賴接口,而不是具體實現(xiàn)。

事件驅(qū)動:使用Spring的ApplicationEvent解耦:

@Service
public class ServiceA {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void doSomething() {
        eventPublisher.publishEvent(new CustomEvent(data));
    }
}

@Component
public class ServiceB {
    @EventListener
    public void handleEvent(CustomEvent event) {
        // 處理事件
    }
}

3.2 方案2:使用@Lazy注解(次優(yōu)方案)

如果暫時無法重構(gòu),可以在其中一個依賴上使用@Lazy,延遲初始化Bean:

@Service
public class ServiceA {
    @Lazy  // 延遲注入
    @Autowired
    private ServiceB serviceB;
}

缺點:

  • 只是延遲問題,而不是真正解決循環(huán)依賴。
  • 可能導(dǎo)致運行時NPE(NullPointerException)。

3.3 方案3:允許循環(huán)依賴(臨時方案)

如果必須保留循環(huán)依賴,可以在application.properties中啟用:

spring.main.allow-circular-references=true

缺點:

  • 只是繞過問題,可能導(dǎo)致不可預(yù)見的初始化順序問題。
  • 不推薦在生產(chǎn)環(huán)境使用。

4. 深入理解Spring的循環(huán)依賴處理機(jī)制

4.1 Spring的三級緩存

Spring通過三級緩存解決部分循環(huán)依賴問題:

  • Singleton Objects(一級緩存):存放完全初始化好的Bean。
  • Early Singleton Objects(二級緩存):存放半成品Bean(已實例化但未初始化)。
  • Singleton Factories(三級緩存):存放Bean工廠,用于生成代理對象。

4.2 循環(huán)依賴的解決條件

  • 僅適用于單例(Singleton)作用域的Bean。
  • 僅適用于字段注入(@Autowired)或Setter注入,不適用于構(gòu)造器注入。

5. 最佳實踐總結(jié)

方案適用場景優(yōu)點缺點
重構(gòu)代碼長期項目徹底解決問題,代碼更清晰需要設(shè)計調(diào)整
@Lazy注解短期修復(fù)簡單快捷可能隱藏問題
允許循環(huán)依賴緊急修復(fù)快速繞過問題不推薦,可能導(dǎo)致未知錯誤

推薦做法:

  • 避免雙向依賴,盡量采用單向依賴(Controller → Service → Repository)。
  • 提取公共邏輯到新Service或Utils類。
  • 使用事件驅(qū)動(ApplicationEvent)解耦Service。
  • 盡量使用構(gòu)造器注入,避免字段注入(能提前發(fā)現(xiàn)循環(huán)依賴問題)。

6. 示例代碼:重構(gòu)后的結(jié)構(gòu)

6.1 原結(jié)構(gòu)(循環(huán)依賴)

@Service
public class ServiceA {
    @Autowired
    private ServiceB serviceB;
}

@Service
public class ServiceB {
    @Autowired
    private ServiceA serviceA;
}

6.2 重構(gòu)后(解耦)

// 提取公共邏輯到新Service
@Service
public class CommonService {
    // 公共方法
}

// ServiceA 依賴 CommonService
@Service
public class ServiceA {
    @Autowired
    private CommonService commonService;
}

// ServiceB 依賴 CommonService
@Service
public class ServiceB {
    @Autowired
    private CommonService commonService;
}

7. 結(jié)論

循環(huán)依賴是Spring Boot開發(fā)中的常見問題,通常表明設(shè)計上存在優(yōu)化空間。雖然可以通過@Lazyallow-circular-references臨時解決,但重構(gòu)代碼才是最佳實踐。

關(guān)鍵點總結(jié):

  • 避免雙向依賴,盡量保持單向依賴鏈。
  • 優(yōu)先使用構(gòu)造器注入,能更早發(fā)現(xiàn)循環(huán)依賴問題。
  • 提取公共邏輯或使用事件驅(qū)動解耦Service。
  • 不要濫用@Lazyallow-circular-references,它們只是臨時解決方案。

通過合理設(shè)計,我們可以構(gòu)建更健壯、可維護(hù)的Spring Boot應(yīng)用! 

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

相關(guān)文章

  • java正則替換img標(biāo)簽中src值的方法

    java正則替換img標(biāo)簽中src值的方法

    今天小編就為大家分享一篇java正則替換img標(biāo)簽中src值的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • JavaEE通過response實現(xiàn)請求重定向

    JavaEE通過response實現(xiàn)請求重定向

    這篇文章主要介紹了JavaEE通過response實現(xiàn)請求重定向的方法,非常的簡單實用,有需要的朋友可以參考下
    2014-10-10
  • ScrollView中嵌入ListView只顯示一條的解決辦法

    ScrollView中嵌入ListView只顯示一條的解決辦法

    在ScrollView添加一個ListView會導(dǎo)致listview控件顯示不全,通常只會顯示一條,究竟是什么原因呢?下面腳本之家小編給大家介紹ScrollView中嵌入ListView只顯示一條的解決辦法,感興趣的朋友一起學(xué)習(xí)吧
    2016-05-05
  • 深入理解Java的接口與抽象類

    深入理解Java的接口與抽象類

    本文主要介紹java 的接口和抽象類,對接口和抽象類進(jìn)行介紹對比,深入理解,有需要的小伙伴可以參考下
    2016-07-07
  • 使用Swagger時Controller中api接口顯示不全的問題分析及解決

    使用Swagger時Controller中api接口顯示不全的問題分析及解決

    swagger是一個十分好用的api接口管理、測試框架,現(xiàn)在越來越多的人使用這個做接口的測試和管理,但經(jīng)常遇到Controller中的api接口顯示不全的問題,所以本文給大家詳細(xì)分析了問題以及解決方法,需要的朋友可以參考下
    2024-02-02
  • Java依賴注入容器超詳細(xì)全面講解

    Java依賴注入容器超詳細(xì)全面講解

    依賴注入(Dependency Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個概念。具體含義是:當(dāng)某個角色(可能是一個Java實例,調(diào)用者)需要另一個角色(另一個Java實例,被調(diào)用者)的協(xié)助時,在 傳統(tǒng)的程序設(shè)計過程中,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實例
    2023-01-01
  • Elasticsearch倒排索引詳解及實際應(yīng)用中的優(yōu)化

    Elasticsearch倒排索引詳解及實際應(yīng)用中的優(yōu)化

    Elasticsearch(ES)使用倒排索引來加速文本的搜索速度,倒排索引之所以高效,主要是因為它改變了數(shù)據(jù)的組織方式,使得查詢操作可以快速完成,這篇文章主要給大家介紹了關(guān)于Elasticsearch倒排索引詳解及實際應(yīng)用中優(yōu)化的相關(guān)資料,需要的朋友可以參考下
    2024-08-08
  • Java實現(xiàn)將Word文檔轉(zhuǎn)換為密碼保護(hù)的PDF文件

    Java實現(xiàn)將Word文檔轉(zhuǎn)換為密碼保護(hù)的PDF文件

    在數(shù)字化辦公中,Word文檔的安全共享常面臨挑戰(zhàn),本文將借助Spire.Doc for Java庫,實現(xiàn)Word文檔到加密PDF的無縫轉(zhuǎn)換,確保敏感內(nèi)容的分發(fā)安全,滿足企業(yè)級文檔管理的合規(guī)需求,有需要的可以參考下
    2025-10-10
  • java隨機(jī)生成8位數(shù)授權(quán)碼的實例

    java隨機(jī)生成8位數(shù)授權(quán)碼的實例

    下面小編就為大家?guī)硪黄猨ava隨機(jī)生成8位數(shù)授權(quán)碼的實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • java基礎(chǔ)之 Arrays.toString()方法詳解

    java基礎(chǔ)之 Arrays.toString()方法詳解

    這篇文章主要介紹了java基礎(chǔ)之 Arrays.toString()方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02

最新評論

雅安市| 南开区| 台安县| 澄迈县| 南召县| 县级市| 开化县| 台山市| 隆子县| 兴仁县| 南阳市| 许昌县| 水城县| 吉木乃县| 宣城市| 堆龙德庆县| 疏勒县| 都兰县| 郴州市| 阿荣旗| 潼关县| 灌南县| 贡山| 兴宁市| 枣庄市| 弥渡县| 巴林左旗| 泾源县| 玉林市| 宁波市| 巴林左旗| 秦安县| 黑河市| 乳源| 满城县| 台安县| 宁武县| 清流县| 抚顺市| 双峰县| 邻水|