徹底理解Spring三級緩存機制

文章目錄

  • 前言
  • 一、Spring解決循環依賴時,為什么要使用三級緩存?


前言

??Spring解決循環依賴的手段,是通過三級緩存

  • singletonObjects:存放所有生命周期完整的單例對象。(一級緩存)
  • earlySingletonObjects:存放所有完成了實例化操作的早期單例對象。(二級緩存)
  • singletonFactories:存放單例工廠的對象,通過工廠創建早期Bean。(三級緩存)
    在這里插入圖片描述
    ??具體Spring是如何解決循環依賴問題的,在Spring循環依賴源碼分析中已經詳細說明,本篇側重于證明三級緩存的必要性。

一、Spring解決循環依賴時,為什么要使用三級緩存?

??這是一道非常經典的面試題。如果一個對象需要被代理,那首先需要生成一個普通的對象,而代理對象和普通對象是不能同時存在于容器中的,當一個對象需要使用代理的時候,就要使用代理對象覆蓋掉原來的普通對象。
??這是一個典型的循環依賴場景,存在兩個相互引用的 Bean:A 和 B。其中 A 包含 b 屬性,B 包含 a 屬性。無論是否存在循環依賴,這兩個 Bean 在完成實例化后都會自動存入三級緩存。需要注意的是,通過反射創建的實例對象與放入三級緩存工廠中的對象實際上是同一個引用在這里插入圖片描述
??然后A對象執行屬性注入,發現需要B屬性,B在容器中是不存在的,于是需要去創建B對象。
??B對象在執行屬性注入,發現需要A屬性,需要從容器中獲取:
在這里插入圖片描述
??這里從三級緩存中,可以獲取到創建A對象的工廠方法,如果A對象需要AOP,則會:
在這里插入圖片描述
??為B的A屬性賦值時,使用的是經過AOP處理的A對象。在B完成初始化后,A對象完成屬性注入并繼續初始化流程,此時不會再次進行AOP處理。這意味著A對象和B對象中的A屬性實際上指向同一個經過AOP處理的對象實例。這就是三級緩存存在的意義。
??如果僅使用二級緩存,給B的A屬性賦值的是未經AOP處理的原始A對象。隨后A繼續完成后續生命周期并經過AOP處理,導致最終生成的A對象與B持有的A對象不同——前者經過AOP增強,而后者仍是原始對象


??這里可能會有一個疑惑的點,那就是,A對象和B中的A屬性應該是同一個實例,如果A繼續完成后續生命周期并執行AOP處理,最終將成為AOP增強對象。那么即便最初B獲取A屬性時,A尚未經過AOP處理,當A完成整個流程后,B中的A是否也會自動成為AOP增強對象?
??答案是否定的,因為Spring 中對 A 做 AOP 是通過“生成一個新的代理對象”,而不是修改原始 A 的引用本身:

  • B 中的 a 是早期注入進去的,它的類型是原始 A
  • Spring 后續創建了 proxyA,它是一個新對象,代理了原始 A
  • 但此時 B 中早就注入好了,不會“回頭替換”那個引用
  • 所以 B 中的 A 就是原始對象,沒有事務、沒有切面

??一個簡單案例即可證明:

public class MyService {public void doSomething() {System.out.println("Doing something...");}
}
@Aspect
public class LogAspect {@Before("execution(* MyService.*(..))")public void before() {System.out.println(">>> [AOP] Before method execution");}
}
public class AopTest {public static void main(String[] args) {MyService target = new MyService();// 創建代理工廠并添加切面AspectJProxyFactory factory = new AspectJProxyFactory(target);factory.addAspect(new LogAspect());// 獲取代理對象MyService proxy = factory.getProxy();System.out.println("target = " + target.getClass());System.out.println("proxy  = " + proxy.getClass());System.out.println("是否同一引用: " + (target == proxy));proxy.doSomething();}
}

在這里插入圖片描述

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

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

相關文章

【 SpringCloud | 微服務 網關 】

單體架構時我們只需要完成一次用戶登錄、身份校驗,就可以在所有業務中獲取到用戶信息。而微服務拆分后,每個微服務都獨立部署,這就存在一些問題: 每個微服務都需要編寫登錄校驗、用戶信息獲取的功能嗎? 當微服務之間調…

【前端面經】字節跳動一面

寫在前面:面經只是記錄博主遇到的題目。每題的答案在編寫文檔的時候已經有問過deepseek,它只是一種比較普世的答案,要學得深入還是靠自己 Q:三欄布局的實現方式(圣杯模型)如何實現 A: /* 整個 …

ST-GCN

1.bash 安裝git 在目錄下右鍵使用git bash打開 需要安裝wgetbash download_model.sh,下載.sh文件 wget: command not found,Windows系統使用git命令 下載預訓練權重_sh文件下載-CSDN博客 bash tools/get_models.sh 生成了三個.pt文件

計算機網絡全維度解析:架構協議、關鍵設備、安全機制與新興技術深度融合

計算機網絡作為當今數字化社會的基石,其復雜性和應用廣泛性遠超想象。本文將從基礎架構、協議體系、關鍵設備、安全機制到新興技術,進行全方位、深層次的解析,并輔以實際應用場景和案例分析。 一、網絡架構與分類的深度剖析 1.1 網絡分類的立…

大語言模型的推理能力

2025年,各種會推理的AI模型如雨后春筍般涌現,比如ChatGPT o1/o3/o4、DeepSeek r1、Gemini 2 Flash Thinking、Claude 3.7 Sonnet (Extended Thinking)。 對于工程上一些問題比如復雜的自然語言轉sql,我們可能忍受模型的得到正確答案需要更多…

黑馬程序員C++核心編程筆記--3 函數高級

3.1 函數默認參數 本節內容之前已經整理過,詳見22.函數的默認值 3.2 函數占位參數 C中函數的形參列表里可以有占位參數,用來做占位,調用函數時必須補填該位置 語法: 返回值類型 函數名 (數據類型) {} 在現階段函數的占位參數…

數據倉庫分層 4 層模型是什么?

企業每天都在產生和收集海量數據。然而,面對這些數據,許多企業卻陷入了困境:如何高效管理、處理和分析這些數據?如何從數據中提取有價值的信息來支持業務決策?這些問題困擾著眾多數據分析師和 IT 管理者。 在眾多架構…

Java正則表達式完全指南

Java正則表達式完全指南 一、正則表達式基礎概念1.1 什么是正則表達式1.2 Java中的正則表達式支持 二、正則表達式基本語法2.1 普通字符2.2 元字符2.3 預定義字符類 三、Java中正則表達式的基本用法3.1 編譯正則表達式3.2 創建Matcher對象并執行匹配3.3 常用的Matcher方法 四、…

緩存擊穿、緩存雪崩、緩存穿透以及數據庫緩存雙寫不一致問題

在項目中,我們所需要的數據通常存儲在數據庫中,但是數據庫的數據保存在硬盤上,硬盤的讀寫操作很慢,為了避免直接訪問數據庫,我們可以使用 Redis 作為緩存層,緩存通常存儲在內存中,內存的讀寫速度…

可靈2.1 vs Veo 3:AI視頻生成誰更勝一籌?

在Google發布Veo 3幾天后,可靈顯然感受到了壓力,發布了即將推出的視頻模型系列可靈 2.1的早期體驗版。 據我了解,有三種不同的模式: 可靈 2.1 標準模式: 720p分辨率 僅支持圖像轉視頻(生成更快,一致性更好) 5秒視頻仍需20積分 可靈 2.1 專業模式: 1080p分辨率 僅在圖…

解決Docker存儲空間不足問題

虛擬機磁盤擴展實戰:解決Docker存儲空間不足問題 問題背景 在虛擬機中運行的Linux系統上,Docker服務因根分區空間不足而無法正常運行。初始狀態如下: [rootlocalhost ~]# df -h / 文件系統 容量 已用 可用 已用% 掛載點…

Redis 中如何保證緩存與數據庫的數據一致性?

在 Redis 中保證緩存與數據庫的數據一致性,需結合業務場景選擇以下策略: 核心策略總結 Cache Aside(旁路緩存)模式 讀操作:先查緩存,未命中則查數據庫并寫入緩存。寫操作:先更新數據庫&#xf…

晶振頻率穩定性:5G 基站與航天設備的核心競爭力

在當今科技飛速發展的時代,電子設備的性能和可靠性至關重要。晶振作為電子設備中的核心部件,為系統提供精確的時間和頻率基準。晶振的頻率穩定性直接影響著設備的整體性能,從日常生活中廣泛使用的智能手機、智能穿戴設備,到對精度…

PDFGear——完全免費且功能強大的PDF處理軟件

關鍵詞 :PDFGear、免費、跨平臺、多功能、OCR 概要 :PDFGear是一款完全免費且功能強大的PDF處理軟件,支持Windows、macOS、iOS和Android等多平臺使用。它集PDF閱讀、編輯、格式轉換、OCR識別及AI智能助手于一體,滿足用戶多樣化文檔…

【筆記】在 MSYS2(MINGW64)中正確安裝 Rust

#工作記錄 1. 環境信息 Windows系統: MSYS2 MINGW64當前時間: 2025年6月1日Rust 版本: rustc 1.87.0 (17067e9ac 2025-05-09) (Rev2, Built by MSYS2 project) 2. 安裝步驟 步驟 1: 更新系統包數據庫并升級已安裝的包 首先,確保我們的 MSYS2 系統是最新狀態。打…

WIN11+VSCODE搭建的c/c++環境調試報錯解決

解決調試報錯 前面win11vscode搭建的c/c環境,ctrlshiftB生成正常,cttlF5運行正常。今天打斷點逐步調試時報錯,提示找不到庫文件。解決方案如下: 下載mingw-w64源碼庫:(兩種途徑) 通過MSYS2 UC…

React項目在ios和安卓端要做一個漸變色背景,用css不支持,可使用react-native-linear-gradient

以上有個模塊是灰色逐漸到白的背景色過渡 如果是css,以下代碼就直接搞定 background: linear-gradient(180deg, #F6F6F6 0%, #FFF 100%);但是在RN中不支持這種寫法,那應該寫呢? 1.引入react-native-linear-gradient插件,我使用的是…

android-studio-2024.3.2.14如何用WIFI連接到手機(給數據線說 拜拜!)

原文:Android不用數據線就能調試真機的方法—給數據線說 拜拜!(adb遠程調試) android-studio-2024.3.2.14是最新的版本,如何連接到手機,可用WIFI,可不用數據線,拜拜 第一步&#xf…

【前端】JS引擎 v.s. 正則表達式引擎

JS引擎 v.s. 正則表達式引擎 它們的轉義符都是\ 經過JS引擎會進行一次轉義 經過正則表達式會進行一次轉義在一次轉義中\\\\\的轉義過程: 第一個 \ (轉義符) 會“吃掉”第二個 \,結果是得到一個字面量的 \。 第三個 \ (轉義符) 會“吃掉”第四個 \&#x…

ReactHook有哪些

React 中常用的 Hooks 列表及用法 React Hooks 是 React 16.8 版本引入的一項重要特性,它極大地簡化和優化了函數組件的開發過程。以下是 React 中常用的 Hooks 列表及其詳細用法: 1. useState useState 是用于在函數組件中添加狀態的 Hook。通過調用…