Spring迴圈依賴問題(筆記)

2021-10-22 17:49:38 字數 1565 閱讀 3336

a類中有成員變數b類的物件。

b類中也有成員變數a類的物件。

// 簡單來說就,就是如下情況

class a

class b

在一開始的開始

也就是程式第一次獲取a的例項時,需要從spring容器單例池中獲取。但此時單例池中還沒有a的例項,所以要new 乙個a物件。

在a例項 建立和初始化的時候,要獲取成員變數b的例項,這也需要從單例池中獲取,但此時b類在池子中也沒有物件,也需要new乙個。

在b例項 建立和初始化的時候,要獲取成員變數a的例項,這就造成了在建立的時候迴圈依賴,都需要對方乙個已經建立好的例項。

乙個單例池肯定是不夠的,增加乙個半成品池,也就是二級快取的機制。

在第一步a例項化之後,將a的半成品例項放到這個半成品池子當中,這樣子,當b初始化的時候,直接從半成品池子獲取a的半成品例項,等b初始化完成之後,再完成a之後初始化操作。

最後將a的例項從半成品 轉移到 單例池中,即可解決 迴圈依賴的問題。

在aop的情景, a的成員變數b,不是b的例項,而是b的動態**例項 ,可以看做 $b。

而b的成員變數a,也不是a的例項,而是a的動態**例項,可以看做 $a.

如果繼續採用二級快取的話,半成品池子裡面放的只有 例項,而不是 動態**例項,是行不通的。

需要乙個 工廠池,也就是**快取的機制,用來獲取a的**物件。

在上面步驟中,a例項建立時,在工廠池 中新增乙個 半成品的a。

然後在初始化的時候需要乙個b的動態**例項,於是走b的建立初始化流程。

b例項建立時,也會在工廠池中新增乙個半成品的b,

然後b初始化的時候,從工廠池中獲取半成品a,並呼叫他的提前引用方法,獲取到a的動態**物件,也就是$a. 

將動態**例項 $a 放入到 半成品池子裡面去。再用半成品池裡面 $a 去填充b例項裡面的成員變數a。

完成後續b的初始化操作之後,呼叫b物件的後置處理,建立動態**例項 $b,並將$b 放入到 單例池裡面去,b的例項化操作便完成了。

b完成之後,又回到a的初始化後續步驟,直接將$b 從單例池中賦值給a的成員變數即可。

當然,同樣會呼叫a的後置處理,但因為前面通過提前引用的方式,已經建立了a的動態**例項$a,所以後置處理並不會再去建立 a的動態**例項,此時直接將$a 從半成品池中遷移到單例池即可。

spring 解決迴圈依賴的思路基本就這樣了,**快取機制。

Spring 迴圈依賴問題

a class com.demo.circularreference.a name b ref b bean b class com.demo.circularreference.b name a ref a bean public classa public class b spring中將迴圈依...

spring迴圈依賴問題

在開始介紹各種情況之前,首先要了解以下三個知識點 spring中依賴注入的方式有兩種,屬性注入與構造器注入。上面的 中,類a就是通過屬性注入的方式注入了b,類b是通過構造器注入的方式注入了a。spring中的bean根據作用域的不同,可以大體分為兩類,singleton和prototype。sing...

Spring解決迴圈依賴 筆記

參考 spring內部維護了三個map,也就是我們通常說的 快取,位置在defaultsingletonbeanregistry private final mapsingletonobjects new concurrenthashmap 256 private final map singlet...