回覆列表
-
1 # 程式設計師阿照
-
2 # 21Char
簡單來講,第三級快取是為了解決迴圈依賴的物件是aop代理物件的這種情況,用來提前對早期物件進行動態代理的,這需要你明白aop是怎麼初始化的以後就懂為啥要用三級了,但這是對aop代理這種特殊情況,大部分情況兩級快取足夠了
簡單來講,第三級快取是為了解決迴圈依賴的物件是aop代理物件的這種情況,用來提前對早期物件進行動態代理的,這需要你明白aop是怎麼初始化的以後就懂為啥要用三級了,但這是對aop代理這種特殊情況,大部分情況兩級快取足夠了
spring是如何解決單例的迴圈依賴注入
首先看下面三個快取:
1.singletonObjects:存放初始化好的bean
2.earlySingletonObjects:存放了剛例項化好的,但是還未配置屬性和初始化的bean,我們在獲取該bean的時候會呼叫beanPostProcessor的getEarlyReference進行一些提前獲取bean的必要操作
3.singletonFactories:存放我剛例項化的bean,透過ObjectFactory,可以讓如果有提前需要bean的需要可以呼叫該
objectfactory 其會將剛例項化好的bean經過beanPostProcessor的getEarlyReference處理進行返回
我們先例項化A,例項化好後
呼叫addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
() -> getEarlyBeanReference(beanName, mbd, bean)是objectFactory的實現匿名類,然後此時我們設定屬性的時候會發現我們還依賴B,於是我們去例項化B而當我們此時例項化B的會經過下面這個方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
首先從singletonObjects獲取是否存在以及初始化好的bean
Object singletonObject = this.singletonObjects.get(beanName);
如果沒有,且依賴的A正在初始化,那我們去嘗試看看earlySingletonObjects是否有物件
earlySingletonObjects存放的是還未例項化好物件
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
因為我們初始化bean都是加鎖的,但是這邊的鎖對於迴圈依賴是沒用的,因為我們都是例項化好物件
準備設定屬性的時候才發現迴圈依賴這個時候再去建立依賴物件,都是同一個執行緒此時鎖是可重入的
synchronized (this.singletonObjects) {
從earlySingletonObjects獲取
singletonObject = this.earlySingletonObjects.get(beanName);
獲取不到 但是支援獲取EarlyReference
if (singletonObject == null && allowEarlyReference) {
我們獲取objectfactory,這個objectfactory就是
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
中的() -> getEarlyBeanReference(beanName, mbd, bean),然後吧結果放入
earlySingletonObjects,我們在整個單例建立結束的時候在把正在初始化好的物件放入
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
由此可見 如果之前已經把A存放在singletonFactories,那麼B會把其調出來放入earlySingletonObjects,然後整個單例建立完成在塞入singletonObjects。存放在singletonFactories好處是可擴充套件,我們在這個裡面會呼叫beanPostProcessor 從而可以在我們實現提前獲取物件引用的時候進行一些操作