Spring 三級緩存 vs 二級緩存:深度解析循環依賴的終極解決方案

目錄

一. 循環依賴的本質矛盾

1. 什么是循環依賴?

2. 矛盾的核心

二.? 三級緩存架構解析

三級緩存工作流程圖?編輯

三、為什么必須三級緩存?

1. 二級緩存的致命缺陷

2. 三級緩存的精妙設計

四、場景推演:三級緩存如何解決代理問題

1. 正常流程(無循環依賴)

2. 循環依賴流程??編輯

五、源碼級驗證

1. 三級緩存獲取邏輯

?2. 代理對象生成點

六、如果強行使用二級緩存

在 Spring 框架中,循環依賴(Circular Dependency)是開發過程中最常見的陷阱之一。Spring 通過三級緩存機制優雅地解決了這一問題,但許多開發者會疑惑:為什么需要三級緩存?二級緩存能否實現同樣的效果?本文將通過源碼分析、場景推演和設計哲學,揭示這一機制背后的精妙設計。


一. 循環依賴的本質矛盾

1. 什么是循環依賴?

當兩個或多個 Bean 相互依賴時,就會形成循環依賴:

// Bean A 依賴 Bean B
@Component
public class A {@Autowiredprivate B b;
}// Bean B 依賴 Bean A
@Component
public class B {@Autowiredprivate A a;
}

2. 矛盾的核心

  • 構造器注入無法解決循環依賴:必須通過 Setter 或字段注入。

  • Bean 創建的生命周期沖突

二.? 三級緩存架構解析

Spring 通過三級緩存解決循環依賴問題,其核心數據結構如下:

緩存級別數據結構存儲內容
一級緩存singletonObjects完全初始化完成的單例 Bean
二級緩存earlySingletonObjects提前暴露的早期 Bean(未完成屬性注入)
三級緩存singletonFactoriesBean 的 ObjectFactory(用于生成代理對象)

三級緩存工作流程圖

三、為什么必須三級緩存?

1. 二級緩存的致命缺陷

假設只有一級緩存 + 二級緩存

  • 場景:Bean A 依賴 Bean B,Bean B 依賴 Bean A,且 A 需要 AOP 代理

  • 問題鏈

    1. A 實例化后放入二級緩存(原始對象)

    2. B 從二級緩存獲取 A 的原始對象并注入

    3. A 完成初始化后需要生成代理對象

    4. 結果:B 中持有的是 A 的原始對象,與最終代理對象不一致

2. 三級緩存的精妙設計

通過?ObjectFactory?延遲處理代理:

// AbstractAutowireCapableBeanFactory
protected Object getEarlyBeanReference(String beanName, Object bean) {// 通過后置處理器生成代理對象return applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
  • 動態決策:只有在發生循環依賴時才會調用 ObjectFactory

  • 代理一致性:保證所有依賴方拿到的是同一個代理對象


四、場景推演:三級緩存如何解決代理問題

1. 正常流程(無循環依賴)

2. 循環依賴流程?

五、源碼級驗證

1. 三級緩存獲取邏輯

// DefaultSingletonBeanRegistry
protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;
}

?2. 代理對象生成點

// AbstractAutowireCapableBeanFactory
protected Object doCreateBean(...) {// 1. 實例化對象instanceWrapper = createBeanInstance(beanName, mbd, args);// 2. 加入三級緩存addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));// 3. 屬性填充(可能觸發循環依賴)populateBean(beanName, mbd, instanceWrapper);// 4. 初始化(生成最終代理對象)exposedObject = initializeBean(beanName, exposedObject, mbd);
}

六、如果強行使用二級緩存?

假設合并三級緩存中的?singletonFactories?和?earlySingletonObjects,會導致:

  1. 提前暴露未完成對象:可能將半成品 Bean 暴露給其他線程

  2. 代理對象不一致:普通 Bean 與代理 Bean 可能同時存在

  3. 內存泄漏風險:無法及時清理創建失敗的 Bean 引用

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/71263.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/71263.shtml
英文地址,請注明出處:http://en.pswp.cn/web/71263.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

視頻流暢播放相關因素

視頻播放的流暢度是一個綜合性問題&#xff0c;涉及從視頻文件本身到硬件性能、網絡環境、軟件優化等多個環節。以下是影響流暢度的關鍵因素及優化建議&#xff1a; 一、視頻文件本身 1. 分辨率與幀率 1.問題&#xff1a;高分辨率&#xff08;如4K&#xff09;或高幀率&#…

金融項目實戰

測試流程 測試流程 功能測試流程 功能測試流程 需求評審制定測試計劃編寫測試用例和評審用例執行缺陷管理測試報告 接口測試流程 接口測試流程 需求評審制定測試計劃分析api文檔編寫測試用例搭建測試環境編寫腳本執行腳本缺陷管理測試報告 測試步驟 測試步驟 需求評審 需求評…

LeetCode 25 - K 個一組翻轉鏈表

LeetCode 25 - K 個一組翻轉鏈表 這道題是一個典型的鏈表操作題&#xff0c;考察我們對鏈表的精確操作&#xff0c;包括反轉鏈表、分組處理、遞歸和迭代的結合應用等。還可以通過變體問題延伸到優先隊列操作、歸并、分塊等&#xff0c;這使得它成為面試中的高頻考題之一。 題目…

Leetcode 54: 螺旋矩陣

Leetcode 54: 螺旋矩陣 是一道經典的矩陣遍歷模擬題目&#xff0c;要求我們以螺旋順序遍歷一個二維數組。這個問題在面試中非常經典&#xff0c;考察模擬、數組操作以及邏輯清晰度。掌握本題的高效解法可以迅速給面試官留下好印象。 適合面試的解法&#xff1a;邊界法&#xff…

abseil-cpp:環境搭建

參考: https://abseil.io/docs/cpp/quickstart-cmake abseil-cpp.git/dd4c89b abseil-cpp.git/20240722.1 1. clone代碼倉庫、編譯 git clone https://github.com/abseil/abseil-cpp.git /app/abseil-cpp/ #/app/abseil-cpp/.git/config git checkout 20240722.1git rev-pa…

Storm實時流式計算系統(全解)——下

storm編程案例-網站訪問來源實時統計-需求 storm編程-網站訪問來源實時統計-代碼實現 根據以上條件可以只寫一個類&#xff0c;我們只需要寫2個方法和一個main&#xff08;&#xff09;&#xff0c;一個讀取/發射&#xff08;spout&#xff09;。 一個拿到數據統計后發到redis…

什么是SYN洪范攻擊?

文章目錄 一、什么是SYN洪范攻擊&#xff1f;二、SYN泛洪攻擊原理2.1 TCP 三次握手過程2.2 SYN攻擊過程 三、防御措施 一、什么是SYN洪范攻擊&#xff1f; SYN洪泛攻擊&#xff08;SYN Flood&#xff09;發生在OSI第四層&#xff0c;是一種基于?TCP協議三次握手漏洞?的DoS&a…

【嵌入式】MQTT

MQTT 文章目錄 MQTT安裝簡介MQTT客戶端代碼 安裝 安裝Paho MQTT C庫: sudo apt-get install libpaho-mqtt3-dev頭文件包含&#xff1a; #include "MQTTClient.h"編譯選項&#xff1a; gcc -o $ $^ -lpaho-mqtt3c簡介 MQTT協議全稱是&#xff08;Message Queuing…

ubuntu離線安裝nvidia-container-runtime

參考文章 ubuntu系統docker20.4版本安裝nvidia-container-runtime3.11.0-1版本(離線安裝nvidia-docker) - jokerMM - 博客園 https://zhuanlan.zhihu.com/p/15194336245 一、軟件地址 Index of /nvidia-docker/libnvidia-container/stable/ 從上述地地址——進入對應系統—…

用Python+Flask打造可視化武俠人物關系圖生成器:從零到一的實戰全記錄

用PythonFlask打造可視化武俠人物關系圖生成器&#xff1a;從零到一的實戰全記錄 一、緣起&#xff1a;一個程序小白的奇妙探索之旅 作為一個接觸Python僅13天的編程萌新&#xff0c;我曾以為開發一個完整的應用是遙不可及的事情。但在DeepSeek的幫助下&#xff0c;我竟用短短…

RPA 職業前景:個人職場發展的 “新機遇”

1. RPA職業定義與范疇 1.1 RPA核心概念 機器人流程自動化&#xff08;RPA&#xff09;是一種通過軟件機器人模擬人類操作&#xff0c;自動執行重復性、規則性任務的技術。RPA的核心在于其能夠高效、準確地處理大量數據和流程&#xff0c;減少人工干預&#xff0c;從而提高工作…

Full GC 排查

在 Java 中&#xff0c;Full GC&#xff08;完全垃圾回收&#xff09;會對整個堆&#xff08;包括年輕代和老年代&#xff0c;甚至可能包括永久代/元空間&#xff09;進行垃圾回收&#xff0c;通常會導致較長的停頓&#xff08;STW&#xff0c;Stop-The-World&#xff09;。如果…

go語言中字符串嵌套

在Go語言中&#xff0c;字符串嵌套通常是指在字符串中包含另一個字符串。可以通過以下幾種方式實現&#xff1a; 1. 使用雙引號和轉義字符 如果需要在字符串中嵌套雙引號&#xff0c;可以使用轉義字符 \ 來表示內部的雙引號。例如&#xff1a; s : "He said, \"He…

Docker 學習(二)——基于Registry、Harbor搭建私有倉庫

Docker倉庫是集中存儲和管理Docker鏡像的平臺&#xff0c;支持鏡像的上傳、下載、版本管理等功能。 一、Docker倉庫分類 1.公有倉庫 Docker Hub&#xff1a;官方默認公共倉庫&#xff0c;提供超過10萬鏡像&#xff0c;支持用戶上傳和管理鏡像。 第三方平臺&#xff1a;如阿里…

js的簡單介紹

一.javascript&#xff08;是什么&#xff09; 是一種運行在客戶端(瀏覽器)的編程語言&#xff0c;實現人機交互效果 作用 網頁特效&#xff08;監聽客戶的一些行為讓網頁做出對應的反饋&#xff09;表單驗證(針對表格數據的合法性進行判斷)數據交互(獲取后臺的數據&#xf…

k8s架構及服務詳解

目錄 1.1.容器是什么1.2.Namespace1.3.rootfs5.1.Service介紹5.1.1.Serice簡介 5.1.1.1什么是Service5.1.1.2.Service的創建5.1.1.3.檢測服務5.1.1.4.在運行的容器中遠程執行命令 5.2.連接集群外部的服務 5.2.1.介紹服務endpoint5.2.2.手動配置服務的endpoint5.2.3.為外部服務…

01. HarmonyOS應用開發實踐與技術解析

文章目錄 前言項目概述HarmonyOS應用架構項目結構Ability生命周期 ArkTS語言特性裝飾器狀態管理 UI組件與布局基礎組件響應式布局樣式與主題 頁面路由與參數傳遞頁面跳轉參數接收 數據綁定與循環渲染數據接口定義循環渲染 條件渲染組件生命周期最佳實踐與性能優化組件復用響應式…

【虛擬機 IP 配置深度剖析】

虛擬機 IP 配置深度剖析 在虛擬機的使用過程中&#xff0c;IP 配置猶如搭建房屋的基石&#xff0c;是確保虛擬機與外部網絡順暢通信、與其他設備高效交互的關鍵所在。本文將以 CentOS 虛擬機為例&#xff0c;深入解讀 IP 配置的奧秘。 一、認識網絡模式 ? NAT 模式&#xf…

【Python 數據結構 5.棧】

目錄 一、棧的基本概念 1.棧的概念 2.入棧 入棧的步驟 3.出棧 出棧的步驟 4.獲取棧頂元素 獲取棧頂元素的步驟 二、 Python中的棧 順序表實現 鏈表實現 三、棧的實戰 1.LCR 123. 圖書整理 I 思路與算法 2.LCR 027. 回文鏈表 思路與算法 3.1614. 括號的最大嵌套深度 思路與算法 …

Machine Learning 初探

前置知識 pandas 讀取文件&#xff1a;read_csv查看信息 describe&#xff1a;查看整體信息&#xff0c;包括每列的平均值、最大最小值、標準差等head&#xff1a;輸出頭部幾行數據columns&#xff1a;輸出所有列名loc&#xff1a;查詢數據&#xff0c;或是根據索引取對應的數…