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

Spring三級緩存解決循環(huán)依賴的解析過程

 更新時間:2025年05月04日 21:02:44   作者:時光不負追夢人  
這篇文章主要介紹了Spring三級緩存解決循環(huán)依賴的解析過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

一、循環(huán)依賴場景

假設存在兩個Bean的相互依賴:

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

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

二、三級緩存定義

DefaultSingletonBeanRegistry 中定義:

// 一級緩存:完整Bean(K:Bean名稱 V:實例化+初始化完成的Bean)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

// 二級緩存:早期暴露對象(K:Bean名稱 V:未完成屬性注入的原始Bean)
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

// 三級緩存:對象工廠(K:Bean名稱 V:ObjectFactory)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

三、解決流程(以ServiceA和ServiceB為例)

1. 創(chuàng)建ServiceA

sequenceDiagram
    participant Container
    participant Cache1 as singletonObjects
    participant Cache2 as earlySingletonObjects
    participant Cache3 as singletonFactories
    
    Container->>Cache1: 檢查ServiceA是否存在
    Cache1-->>Container: 不存在
    Container->>Container: 實例化ServiceA(構造器調用)
    Container->>Cache3: 添加ServiceA的ObjectFactory
    Container->>Container: 開始屬性注入(需要ServiceB)

關鍵代碼段

// AbstractAutowireCapableBeanFactory#doCreateBean
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

2. 發(fā)現需要ServiceB

sequenceDiagram
    participant Container
    participant Cache1
    participant Cache2
    participant Cache3
    
    Container->>Cache1: 檢查ServiceB是否存在
    Cache1-->>Container: 不存在
    Container->>Container: 實例化ServiceB(構造器調用)
    Container->>Cache3: 添加ServiceB的ObjectFactory
    Container->>Container: 開始屬性注入(需要ServiceA)

3. 解決ServiceB對ServiceA的依賴

sequenceDiagram
    participant Container
    participant Cache1
    participant Cache2
    participant Cache3
    
    Container->>Cache1: 查找ServiceA
    Cache1-->>Container: 不存在
    Container->>Cache2: 查找ServiceA
    Cache2-->>Container: 不存在
    Container->>Cache3: 獲取ServiceA的ObjectFactory
    Container->>Container: 執(zhí)行getEarlyBeanReference()
    Container->>Cache2: 將生成的代理對象存入earlySingletonObjects
    Container->>ServiceB: 注入ServiceA的早期引用
    Container->>Container: 完成ServiceB初始化
    Container->>Cache1: 將ServiceB放入singletonObjects

4. 回溯完成ServiceA初始化

sequenceDiagram
    participant Container
    participant Cache1
    participant Cache2
    participant Cache3
    
    Container->>ServiceA: 注入已初始化的ServiceB
    Container->>Container: 執(zhí)行ServiceA的初始化后方法
    Container->>Cache1: 將ServiceA放入singletonObjects
    Container->>Cache2: 移除ServiceA的早期引用
    Container->>Cache3: 移除ServiceA的ObjectFactory

四、關鍵機制詳解

1. getEarlyBeanReference() 的核心作用

protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    // 如果有必要,在此處生成代理對象
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                SmartInstantiationAwareBeanPostProcessor ibp = 
                    (SmartInstantiationAwareBeanPostProcessor) bp;
                bean = ibp.getEarlyBeanReference(exposedObject, beanName);
            }
        }
    }
    return bean;
}

2. 三級緩存必要性分析

緩存級別解決的問題典型場景
singletonFactories處理AOP代理的延遲生成需要保證代理對象的單例性
earlySingletonObjects避免重復創(chuàng)建早期引用多個Bean依賴同一個未完成初始化的Bean
singletonObjects存儲最終可用Bean正常Bean獲取

五、設計約束與限制

1.僅支持單例作用域

原型(prototype)作用域的Bean無法解決循環(huán)依賴,因為Spring不緩存原型Bean

2.構造器注入限制

如果循環(huán)依賴通過構造器注入發(fā)生,無法解決(實例化前就需要完成依賴注入)

3.異步初始化風險

使用@Async等方法增強的Bean可能破壞初始化順序

六、調試技巧

查看緩存狀態(tài) 

DefaultSingletonBeanRegistry 類中設置斷點:

// 查看三級緩存內容
System.out.println("singletonFactories: " + singletonFactories.keySet());
System.out.println("earlySingletonObjects: " + earlySingletonObjects.keySet());
System.out.println("singletonObjects: " + singletonObjects.keySet());

強制拋出循環(huán)依賴異常

在配置類添加:

@Bean
public CircularReferencesBean circularReferencesBean() {
    return new CircularReferencesBean(circularReferencesBean());
}

七、性能優(yōu)化建議

避免過度使用循環(huán)依賴

即使技術可行,也應通過設計模式(如事件驅動)解耦

合理使用@Lazy注解

延遲加載非必要依賴:

@Autowired
@Lazy
private ServiceB serviceB;

監(jiān)控緩存命中率

通過JMX監(jiān)控 singletonObjectsearlySingletonObjects 的比例

總結

Spring的三級緩存機制通過 提前暴露對象引用 + 動態(tài)代理生成 的協(xié)同設計,在保證單例性的前提下,優(yōu)雅地解決了循環(huán)依賴問題。理解該機制需要重點把握Bean生命周期的階段劃分和緩存狀態(tài)的轉換邏輯。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • Java中使用opencsv讀寫csv文件示例

    Java中使用opencsv讀寫csv文件示例

    這篇文章主要介紹了Java中使用opencsv讀寫csv文件示例,本文給出了讀CSV文件、寫CSV文件、自定義分隔符、生成Javabeans等內容,需要的朋友可以參考下
    2015-04-04
  • Spring4.0 MVC請求json數據報406錯誤的解決方法

    Spring4.0 MVC請求json數據報406錯誤的解決方法

    這篇文章主要為大家詳細介紹了Spring4.0 MVC請求json數據報406錯誤的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Windows下apache ant安裝、環(huán)境變量配置教程

    Windows下apache ant安裝、環(huán)境變量配置教程

    這篇文章主要介紹了Windows下apache ant安裝、環(huán)境變量配置教程,ANT的安裝很簡單,本文同時講解了驗證安裝是否成功的方法和使用方法實例,需要的朋友可以參考下
    2015-06-06
  • java實現滑動驗證解鎖

    java實現滑動驗證解鎖

    這篇文章主要為大家詳細介紹了java實現滑動驗證解鎖,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • 重寫equals的同時為何要重寫hashCode?

    重寫equals的同時為何要重寫hashCode?

    這篇文章主要給大家介紹了關于重寫equals的同時為何要重寫hashCode的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • Java 數組內置函數toArray詳解

    Java 數組內置函數toArray詳解

    這篇文章主要介紹了Java 數組內置函數toArray詳解,文本詳細的講解了toArray底層的代碼和文檔,需要的朋友可以參考下
    2021-06-06
  • SpringBoot的ResponseEntity類返回給前端具體講解

    SpringBoot的ResponseEntity類返回給前端具體講解

    這篇文章主要給大家介紹了關于SpringBoot的ResponseEntity類返回給前端的相關資料,ResponseEntity是Spring框架中用于封裝HTTP響應的類,可以自定義狀態(tài)碼、響應頭和響應體,常用于控制器方法中返回特定數據的HTTP響應,需要的朋友可以參考下
    2024-11-11
  • Spring?Boot?+?EasyExcel?+?SqlServer?進行批量處理數據的高效方法

    Spring?Boot?+?EasyExcel?+?SqlServer?進行批量處理數據的高效方法

    在日常開發(fā)和工作中,我們可能要根據用戶上傳的文件做一系列的處理,本篇文章就以Excel表格文件為例,主要介紹了Spring?Boot?+?EasyExcel?+?SqlServer?進行批量處理數據的高效方法,需要的朋友可以參考下
    2024-06-06
  • Java 實現文件批量重命名親測可用(精簡版)

    Java 實現文件批量重命名親測可用(精簡版)

    本文給大家分享一段自己寫的java代碼實現文件批量重命名,親測試過沒有任何問題,大家可以放心使用
    2016-11-11
  • Spring Security OAuth2實現使用JWT的示例代碼

    Spring Security OAuth2實現使用JWT的示例代碼

    這篇文章主要介紹了Spring Security OAuth2實現使用JWT的示例代碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09

最新評論