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

Spring無法解決循環(huán)依賴的五種場景分析

 更新時間:2025年05月26日 10:50:55   作者:霧緣枯  
本文詳細分析Spring框架中五類循環(huán)依賴問題(構(gòu)造器注入、原型作用域、@Async、配置類、BeanPostProcessor),提出應(yīng)急方案如@Lazy、重構(gòu)設(shè)計,并強調(diào)通過單一職責(zé)、依賴倒置等設(shè)計原則避免循環(huán)依賴,需要的朋友可以參考下

一、構(gòu)造器注入引發(fā)的循環(huán)依賴

1. 問題復(fù)現(xiàn)

@Component
public class ServiceA {
    private final ServiceB serviceB;
    
    @Autowired
    public ServiceA(ServiceB serviceB) { // 構(gòu)造器注入
        this.serviceB = serviceB;
    }
}
 
@Component
public class ServiceB {
    private final ServiceA serviceA;
    
    @Autowired
    public ServiceB(ServiceA serviceA) { // 構(gòu)造器注入
        this.serviceA = serviceA;
    }
}

報錯信息:Requested bean is currently in creation: Is there an unresolvable circular reference?

2. 原理分析

  • 三級緩存失效:構(gòu)造器注入要求在實例化階段完成依賴注入,而此時 Bean 尚未放入三級緩存。
  • 生命周期沖突:

3. 解決方案

  • 方案 1:將其中一個 Bean 改為 Setter / 字段注入
  • 方案 2:使用 `@Lazy` 延遲加載
@Autowired
  public ServiceA(@Lazy ServiceB serviceB) { 
      this.serviceB = serviceB;
  }

二、原型(Prototype)作用域的循環(huán)依賴

1. 問題復(fù)現(xiàn)

@Scope("prototype")
@Component
public class PrototypeA {
    @Autowired private PrototypeB b;
}
 
@Scope("prototype")
@Component
public class PrototypeB {
    @Autowired private PrototypeA a;
}

2. 原理分析

  • 緩存機制不生效:原型 Bean 不會存入三級緩存,每次請求都創(chuàng)建新實例。

  • Spring 官方限制:明確說明不處理原型 Bean 的循環(huán)依賴。

3. 解決方案

  • 重構(gòu)設(shè)計:避免原型 Bean 之間的循環(huán)依賴

  • 改用單例:評估是否真的需要原型作用域

三、@Async 注解導(dǎo)致的代理沖突

1. 問題復(fù)現(xiàn)

@Service
public class AsyncServiceA {
    @Autowired private AsyncServiceB serviceB;
    
    @Async
    public void asyncMethod() { /* ... */ }
}
 
@Service
public class AsyncServiceB {
    @Autowired private AsyncServiceA serviceA;
}

2. 原理分析

  • 代理時序問題@Async 通過后置處理器生成代理,可能破壞三級緩存機制。

  • 典型錯誤棧

BeanCreationException: Error creating bean with name 'asyncServiceA': 
Bean with name 'asyncServiceA' has been injected into other beans [...] in their raw version as part of a circular reference.

3. 解決方案

  • 方案 1:對異步方法所在類使用接口代理
@Async
public interface AsyncService {
    void asyncMethod();
}
 
@Service
public class AsyncServiceImpl implements AsyncService { /* ... */ }
  • 方案 2:在注入點添加 @Lazy
@Autowired @Lazy private AsyncServiceA serviceA;

四、Configuration 類之間的循環(huán)依賴

1. 問題復(fù)現(xiàn)

@Configuration
public class ConfigA {
    @Autowired private ConfigB configB;
}
 
@Configuration
public class ConfigB {
    @Autowired private ConfigA configA;
}

2. 原理分析

  • 配置類加載順序:配置類需要優(yōu)先初始化,無法通過常規(guī)循環(huán)依賴解決。

  • Spring 限制@Configuration 類被視為特殊 Bean,其代理機制與普通 Bean 不同。

3. 解決方案

  • 重構(gòu)配置類:合并相關(guān)配置

  • 使用 @DependsOn:明確指定加載順序

@Configuration
@DependsOn("configB")
public class ConfigA { /* ... */ }

五、自定義 BeanPostProcessor 引發(fā)的沖突

1. 問題復(fù)現(xiàn)

@Component
public class CustomProcessor implements BeanPostProcessor {
    @Autowired private ServiceX x; // 依賴其他Bean
}

2. 原理分析

  • 處理器加載時序BeanPostProcessor 需要優(yōu)先初始化,此時普通 Bean 尚未創(chuàng)建。

  • Spring 啟動流程

3. 解決方案

  • 避免在 BeanPostProcessor 中注入其他 Bean

  • 使用延遲注入

private ObjectProvider<ServiceX> xProvider;
  
  public Object postProcessBeforeInitialization(Object bean, String beanName) {
      ServiceX x = xProvider.getIfAvailable();
      // ...
  }

六、終極解決方案工具箱 

問題類型應(yīng)急方案根治方案
構(gòu)造器循環(huán)依賴@Lazy 注解改為 Setter 注入
原型Bean循環(huán)依賴重構(gòu)作用域引入中間類抽象依賴
AOP代理沖突接口代理模式調(diào)整切面作用順序
配置類循環(huán)依賴@DependsOn 指定順序合并配置類
BeanPostProcessor依賴ObjectProvider 延遲獲取分離處理器與業(yè)務(wù)邏輯

結(jié)語:跳出循環(huán)依賴的思維陷阱

Spring 的循環(huán)依賴處理機制體現(xiàn)了框架設(shè)計的高度智慧,但作為開發(fā)者,最優(yōu)雅的解決方案往往不是技術(shù)手段,而是架構(gòu)設(shè)計。通過以下原則可從根本上避免循環(huán)依賴:

  1. 單一職責(zé)原則:拆分臃腫的 Bean

  2. 依賴倒置原則:面向接口編程

  3. 層次化設(shè)計:Controller -> Service -> Repository 的嚴(yán)格分層

以上就是Spring無法解決循環(huán)依賴的五種場景分析的詳細內(nèi)容,更多關(guān)于Spring無法解決循環(huán)依賴的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java笛卡爾積算法原理與實現(xiàn)方法詳解

    Java笛卡爾積算法原理與實現(xiàn)方法詳解

    這篇文章主要介紹了Java笛卡爾積算法原理與實現(xiàn)方法,結(jié)合實例形式較為詳細的分析了笛卡爾積算法的原理及java定義與使用笛卡爾積算法的相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • SpringBoot壓縮json并寫入Redis的示例代碼

    SpringBoot壓縮json并寫入Redis的示例代碼

    由于業(yè)務(wù)需要,存入redis中的緩存數(shù)據(jù)過大,占用了10+G的內(nèi)存,內(nèi)存作為重要資源,需要優(yōu)化一下大對象緩存,所以我們需要對json進行壓縮,本文給大家介紹了SpringBoot如何壓縮Json并寫入redis,需要的朋友可以參考下
    2024-08-08
  • 深入探討Kafka消費者高性能調(diào)優(yōu)與實踐

    深入探討Kafka消費者高性能調(diào)優(yōu)與實踐

    這篇文章主要為大家詳細介紹了Kafka消費者在高負載環(huán)境下的性能優(yōu)化方案,內(nèi)容涵蓋Kafka基本原理,消費者工作機制,源碼解析以及生產(chǎn)環(huán)境中的實戰(zhàn)案例
    2025-06-06
  • 微信小程序訂閱消息推送實戰(zhàn)圖文教程(Java?Spring?Boot?+?Redis)

    微信小程序訂閱消息推送實戰(zhàn)圖文教程(Java?Spring?Boot?+?Redis)

    訂閱消息是微信小程序提供的一種消息推送方式,用戶可以訂閱某個公眾號或小程序的消息,當(dāng)有新消息時,系統(tǒng)會自動推送通知給用戶,這篇文章主要介紹了微信小程序訂閱消息推送(Java Spring Boot+Redis)的相關(guān)資料,需要的朋友可以參考下
    2026-04-04
  • Map之computeIfAbsent使用解讀

    Map之computeIfAbsent使用解讀

    `computeIfAbsent`是Java 8引入的一個Map接口方法,用于簡化在Map中獲取值的操作,如果指定的鍵不存在,它會調(diào)用提供的函數(shù)生成一個新的值,并將其與鍵關(guān)聯(lián),這種方法減少了手動檢查和插入的樣板代碼,使代碼更加簡潔和易讀
    2025-02-02
  • Java執(zhí)行.bat文件的四種高效方法

    Java執(zhí)行.bat文件的四種高效方法

    在Windows操作系統(tǒng)中,.bat 文件是一種批處理腳本文件,它可以包含一系列命令,用于執(zhí)行特定的任務(wù),在Java開發(fā)中,.bat 文件通常用于簡化Java程序的啟動和執(zhí)行過程,本文給大家介紹了Java執(zhí)行.bat文件的四種高效方法,需要的朋友可以參考下
    2025-08-08
  • 從千千靜聽歌詞服務(wù)器獲取lrc歌詞示例分享

    從千千靜聽歌詞服務(wù)器獲取lrc歌詞示例分享

    這篇文章主要介紹了使用PHP從千千靜聽歌詞服務(wù)器獲取lrc歌詞的方法,大家參考使用吧
    2014-01-01
  • kotlin快速入門之標(biāo)準(zhǔn)函數(shù)與靜態(tài)方法

    kotlin快速入門之標(biāo)準(zhǔn)函數(shù)與靜態(tài)方法

    學(xué)完了Kotlin的基礎(chǔ)知識,是時候來來學(xué)習(xí) Kotlin的標(biāo)準(zhǔn)函數(shù)和靜態(tài)方法了,下面這篇文章主要給大家介紹了關(guān)于kotlin快速入門之標(biāo)準(zhǔn)函數(shù)與靜態(tài)方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • Java Lock接口實現(xiàn)原理及實例解析

    Java Lock接口實現(xiàn)原理及實例解析

    這篇文章主要介紹了Java Lock接口實現(xiàn)原理及實例解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-04-04
  • 淺談Java的兩種多線程實現(xiàn)方式

    淺談Java的兩種多線程實現(xiàn)方式

    本篇文章主要介紹了淺談Java的兩種多線程實現(xiàn)方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08

最新評論

南木林县| 连江县| 紫金县| 涞源县| 浦县| 遂平县| 镇原县| 武川县| 云浮市| 绍兴县| 南城县| 凉山| 靖边县| 岫岩| 都兰县| 凭祥市| 龙南县| 娱乐| 景宁| 麻城市| 神木县| 都安| 苏州市| 黎平县| 明水县| 吐鲁番市| 海丰县| 西乡县| 芮城县| 靖边县| 麦盖提县| 双牌县| 曲松县| 修文县| 永平县| 汉源县| 民权县| 台前县| 兴安县| 桦川县| 阳高县|