singleton 三層快取
/** Cache of singleton objects: bean name to bean instance. */
/** 快取單例物件, K-V -> BeanName - Bean 實體 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of early singleton objects: bean name to bean instance. */
/** 快取早期單例物件 */
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
/** Cache of singleton factories: bean name to ObjectFactory. */
/** 快取 Bean 工廠 */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
doGetBean 里的兩種 getSingleton()
doGetBean 一進去呼叫的:

@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 嘗試從快取中獲取成品的目標物件,如果存在,則直接回傳
Object singletonObject = this.singletonObjects.get(beanName);
// 如果快取中不存在目標物件,則判斷當前物件是否已經處于創建程序中,在前面的講解中,第一次嘗試獲取A物件
// 的實體之后,就會將A物件標記為正在創建中,因而最后再嘗試獲取A物件的時候,這里的if判斷就會為true
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 這里的singletonFactories是一個Map,其key是bean的名稱,而值是一個ObjectFactory型別的
// 物件,這里對于A和B而言,呼叫圖其getObject()方法回傳的就是A和B物件的實體,無論是否是半成品
ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 獲取目標物件的實體
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
上一個 getSingleton 回傳值為 null,并且 beanDefition 為 singleton 的作用域時呼叫

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 加鎖
synchronized (this.singletonObjects) {
// 檢查 singletonObjects 快取中是否有
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 檢查是否在執行銷毀
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 將 Bean 添加到 singletonsCurrentlyInCreation 集合中, 表示正在創建
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 呼叫工廠方法
// 也就是呼叫 createBean(beanName, mbd, args)
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 創建成功, 從 singletonsCurrentlyInCreation 移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 將給定的單例物件添加到該工廠的單例快取中
// this.singletonObjects.put(beanName, singletonObject);
// this.singletonFactories.remove(beanName);
// this.earlySingletonObjects.remove(beanName);
// this.registeredSingletons.add(beanName);
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
doCretaeBean 里放入 singletonFactories

回圈依賴總結
解決方法:singleton 家族,三層 cache
- 第一層 singletonObjects(已經初始化完,成品 bean ,通過 getSingleton 的多載方法放入,該多載方法的入參是 beanName 和 ObjectFactory 的未實作方法 getObject,該 ObjectFactory 使用 lamda 形式創建,在其唯一的 getObject 方法中會呼叫 createBean 創建 bean,然后用 addSingleton 方法放入 singletonObjects )
- 第二層 earlySingletonOjbects(半成品 bean,不會直接在某個步驟直接放入,在 doGetBean 方法一進去就呼叫的 getSingleton(beanName) 中,如果 singletonObjects 中沒有,但是 singletonFactores 中有的話,會把 singletonFactories 中該半成品 bean 放入 earlySingleton ,代表未初始化完成但是被依賴)
- 第三層 singletonFactoies (半成品 bean,在 docreateBean 的 createBeanInstance 完成后呼叫 addSingletonFactories 放入,也正是因為在這個時機放入,所以如果因為構造方法出現回圈依賴無法解決,因為 createBeanInstance 最后會呼叫 SimpleInitalizeStagy 的 instant 方法,該方法在 beanDefition 不存在覆寫方法時就會用 JDK 的反射創建物件,創建的方法就是獲得 constructor 然后 newInstance,所以如果在決議 constructor 的引數有回圈依賴,那么當前的半成品還未放入 singletonFactoies)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/262196.html
標籤:java
上一篇:深入了解java中的包和繼承
