深度解析 Spring 源碼:三級緩存機制探究

Spring 框架中的三級緩存機制主要與 `AbstractAutowireCapableBeanFactory` 類中的 `doCreateBean` 方法在解析和創建單例 bean 時所使用的緩存有關。這個機制主要用於解決循環依賴的問題,尤其是在構造器註入的場景下。以下是對 Spring 三級緩存機制的深度解析:

1. 三級緩存的定義

深度解析 Spring 源碼:三級緩存機制探究

* 一級緩存(singletonObjects):存儲完全初始化好的 bean,即 bean 的所有屬性都已被設置,並且完成了初始化方法(如果有的話)的調用。

* 二級緩存(earlySingletonObjects):存儲提前暴露的 bean 實例的原始對象(即未完成屬性填充的對象)。這個緩存主要是為了解決循環依賴的問題。當一個 bean 的創建依賴於另一個尚未創建完成的 bean 時,這個尚未完成的 bean 會被提前暴露到這個二級緩存中,供其他 bean 使用。

* 三級緩存(singletonFactories):存儲 bean 的工廠對象(`ObjectFactory`),用於創建 bean 的實例。這個緩存主要用於解決 AOP 代理的問題。當 bean 需要被 AOP 代理時,Spring 會在這個緩存中保存一個能夠創建代理對象的工廠,而不是直接保存代理對象本身。

 2. 緩存的使用流程

1. 創建 bean:當一個 bean 需要被創建時,Spring 首先會檢查一級緩存(singletonObjects)中是否存在該 bean 的實例。如果存在,則直接返回;否則,進入下一步。

2. 檢查是否存在循環依賴:在創建 bean 的過程中,如果發現該 bean 依賴於另一個尚未創建完成的 bean(即存在循環依賴),那麼 Spring 會嘗試從二級緩存(earlySingletonObjects)中獲取該依賴 bean 的實例。如果找到了,則使用該實例;否則,繼續下一步。

3. 提前暴露 bean:如果發現了循環依賴,但是二級緩存中沒有該依賴 bean 的實例,那麼 Spring 會提前將該 bean 的實例(尚未完成屬性填充的對象)暴露到二級緩存中,供其他 bean 使用。

4. 創建代理對象(如果需要):如果 bean 需要被 AOP 代理,那麼 Spring 會在這個步驟中創建代理對象。但是,代理對象本身並不會直接保存到緩存中,而是會保存一個能夠創建代理對象的工廠(`ObjectFactory`)到三級緩存(singletonFactories)中。

5. 填充屬性:完成 bean 的屬性填充(即依賴註入)。

6. 初始化 bean:調用 bean 的初始化方法(如果有的話)。

7. 完成創建並保存:將完全初始化好的 bean 保存到一級緩存(singletonObjects)中,並從二級緩存(earlySingletonObjects)和三級緩存(singletonFactories)中移除該 bean 的相關條目。

3. 為什麼要使用三級緩存

* 解決循環依賴:二級緩存的存在主要是為了解決循環依賴的問題。通過提前暴露 bean 的實例,可以確保在依賴註入時能夠找到所需的依賴對象。

* 支持 AOP:三級緩存的存在主要是為了支持 AOP。當 bean 需要被 AOP 代理時,Spring 不會直接保存代理對象到緩存中,而是保存一個能夠創建代理對象的工廠。這樣做的好處是,只有當真正需要代理對象時,才會去創建它,從而避免了不必要的性能開銷。

總結

Spring 的三級緩存機制是一個非常重要的特性,它使得 Spring 能夠在保證單例性的同時,支持循環依賴和 AOP。通過合理地使用這三個緩存,Spring 能夠高效地創建和管理 bean,從而確保整個應用程序的穩定性和性能。

分享給朋友:

“深度解析 Spring 源碼:三級緩存機制探究” 的相關文章

html a標簽target屬性

html a標簽target屬性

HTML語言中的標簽用於定義超鏈接。其中,標簽有一個屬性叫做target,它用於指定鏈接在何處打開。目前,標簽的target屬性有以下四個取值:- _self:鏈接會在當前窗口中打開(默認值),這意味著打開新的文檔或資源時,頁面會在當前瀏覽器窗口中重新加載,並將新文檔或資源顯示在當前窗口中。基於以上…

mark元素使用紅色代表及例子

mark元素使用紅色代表及例子

在HTML中,<mark> 元素可以用於標記或強調文本中的重要或關鍵內容。這個元素通常會用醒目的紅色來渲染,因為紅色是一個視覺上非常具有註意力的顏色。在這種情況下,你可以將這些關鍵字用 <mark> 標簽包圍起來,使其突出顯示。這樣可以幫助用戶更快速地發現這個型號是這個品牌的…

meter元素顏色,可以使用CSS樣式來設置顏色

meter元素顏色,可以使用CSS樣式來設置顏色

meter元素可以用於表示已知範圍內的度量值,可以使用CSS樣式來設置顏色。具體來說,可以使用 <code>::-webkit-meter-optimum-value, ::-moz-meter-bar, ::-webkit-meter-bar</code> 偽元素來設置顏色…

css高亮效果,CSS 創建不同高亮效果具體方法及例子

css高亮效果,CSS 創建不同高亮效果具體方法及例子

CSS 可以為  元素創建各種不同的高亮效果,具體方法如下:1. 使用默認的高亮樣式。可以通過樣式修改  元素的背景色和文本顏色,實現自定義高亮效果,例如:```html這是一段需要高亮的文本,這裏面的文本被自定義高亮了,這裏又是正常的文本。.highlight {  …

HTML 和 CSS 實現網頁導航欄和下拉菜單

HTML 和 CSS 實現網頁導航欄和下拉菜單

以下是一組基於 HTML 和 CSS 實現網頁導航欄和下拉菜單的完整代碼:HTML 代碼:CSS 代碼。該代碼實現了一個簡單的網頁導航欄和下拉菜單,其中 `nav` 表示導航欄,`ul` 表示菜單,`li` 表示菜單項,`a` 表示鏈接。通過設置 CSS 樣式,將菜單項設置為了懸停時出現下拉菜單,同…

星空特效的HTML代碼示例

星空特效的HTML代碼示例

以下是一個星空特效的HTML代碼示例:這個代碼會在頁面背景中生成100個閃爍的星星,使得整個頁面看起來像是夜空中的星空。可以在瀏覽器中運行查看效果。這些代碼可以在瀏覽器中運行並產生相應的星空特效。…