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

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

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

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

1. 問題復現(xiàn)

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

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

2. 原理分析

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

3. 解決方案

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

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

1. 問題復現(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. 解決方案

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

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

三、@Async 注解導致的代理沖突

1. 問題復現(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. 問題復現(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. 解決方案

  • 重構配置類:合并相關配置

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

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

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

1. 問題復現(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();
      // ...
  }

六、終極解決方案工具箱 

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

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

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

  1. 單一職責原則:拆分臃腫的 Bean

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

  3. 層次化設計:Controller -> Service -> Repository 的嚴格分層

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

相關文章

  • java多線程編程之使用Synchronized關鍵字同步類方法

    java多線程編程之使用Synchronized關鍵字同步類方法

    JAVA中要想解決“臟數(shù)據(jù)”的問題,最簡單的方法就是使用synchronized關鍵字來使run方法同步,看下面的代碼,只要在void和public之間加上synchronized關鍵字
    2014-01-01
  • java8 BigDecimal類型的List求和方式

    java8 BigDecimal類型的List求和方式

    這篇文章主要介紹了java8 BigDecimal類型的List求和方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-11-11
  • 詳解Java如何實現(xiàn)基于Redis的分布式鎖

    詳解Java如何實現(xiàn)基于Redis的分布式鎖

    在不同進程需要互斥地訪問共享資源時,分布式鎖是一種非常有用的技術手段。這篇文章運用圖文和實例代碼介紹了Java如何實現(xiàn)基于Redis的分布式鎖,文章介紹的很詳細,對Java和Redis剛興趣的朋友們可以參考借鑒,下面來一起看看。
    2016-08-08
  • Java陷阱之a(chǎn)ssert關鍵字詳解

    Java陷阱之a(chǎn)ssert關鍵字詳解

    這篇文章詳細介紹了Java陷阱之a(chǎn)ssert關鍵字,有需要的朋友可以參考一下
    2013-09-09
  • Spring中Bean的加載與SpringBoot的初始化流程詳解

    Spring中Bean的加載與SpringBoot的初始化流程詳解

    這篇文章主要介紹了Spring中Bean的加載與SpringBoot的初始化流程詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • springboot post接口接受json時,轉換為對象時,屬性都為null的解決

    springboot post接口接受json時,轉換為對象時,屬性都為null的解決

    這篇文章主要介紹了springboot post接口接受json時,轉換為對象時,屬性都為null的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java如何基于EasyExcel實現(xiàn)導入數(shù)據(jù)校驗并生成錯誤信息Excel

    Java如何基于EasyExcel實現(xiàn)導入數(shù)據(jù)校驗并生成錯誤信息Excel

    這篇文章主要介紹了Java如何基于EasyExcel實現(xiàn)導入數(shù)據(jù)校驗并生成錯誤信息Excel,為了優(yōu)化項目中的文件導入功能,考慮構建一個基于EasyExcel的通用Excel導入框架,主要解決導入數(shù)據(jù)的校驗問題,避免業(yè)務代碼中堆積大量校驗邏輯,需要的朋友可以參考下
    2024-09-09
  • SpringBoot內(nèi)部外部配置文件加載順序解析

    SpringBoot內(nèi)部外部配置文件加載順序解析

    這篇文章主要介紹了SpringBoot內(nèi)部外部配置文件加載順序解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-07-07
  • Mybatis一對多與多對一查詢處理詳解

    Mybatis一對多與多對一查詢處理詳解

    這篇文章主要給大家介紹了關于Mybatis一對多與多對一查詢處理的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • Java設計模式中的外觀模式詳解

    Java設計模式中的外觀模式詳解

    外觀模式為多個復雜的子系統(tǒng),提供了一個一致的界面,使得調用端只和這個接口發(fā)生調用,而無須關系這個子系統(tǒng)內(nèi)部的細節(jié)。本文將通過示例詳細為大家講解一下外觀模式,需要的可以參考一下
    2023-02-02

最新評論