注意:
- 執行個體化是使用class執行個體化和初始化是執行個體化之後進行的,部落客一直把這個搞混了。是以如果使用後置處理器自定義執行個體化後spring生命周期直接跳過屬性填充這個步驟,表明執行個體化完成
- spring的aop是屬性填充完成之後這一步傳回一個代理對象替換原先的bean實作的。
- 執行個體化之後,spring會提前暴露目前的bean引用對象到三級緩存裡面,這樣可以解決依賴循環問題
spring的三級緩存分類如下:
名稱 | 描述 |
---|---|
singletonObjects | 一級緩存,存放完整的 Bean。 |
earlySingletonObjects | 二級緩存,存放提前暴露的Bean,Bean 是不完整的,未完成屬性注入和執行 init 方法。 |
singletonFactories | 三級緩存,存放的是 Bean 工廠,主要是生産 Bean,存放到二級緩存中。 |
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
//如果目前一級緩存裡面beanName
if (!this.singletonObjects.containsKey(beanName)) {
//加入三級緩存
this.singletonFactories.put(beanName, singletonFactory);
//清除二級緩存
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
依賴注入的時候擷取bean對象
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 一級緩存
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 二級緩存
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 三級緩存
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// Bean 工廠中擷取 Bean
singletonObject = singletonFactory.getObject();
// 放入到二級緩存中
this.earlySingletonObjects.put(beanName, singletonObject);
//清除二級緩存對象
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
備注:
- 一級緩存,這個就是不用重複建立單例對象
- 二級緩存防止産生多個代理對象,否則一級緩存和三級緩存就夠了。假如依賴循環中,後面有多個屬性依賴A的Bean,沒有二級緩存就會建立多個。
-
第三級緩存的目的是為了延遲代理對象的建立,因為如果沒有依賴循環的話,那麼就不需要為其提前建立代理,可以将它延遲到初始化完成之後再建立。
-如果使用二級緩存實作,如果 Spring 選擇二級緩存來解決循環依賴的話,那麼就意味着所有 Bean 都需要在執行個體化完成之後就立馬為其建立代理,而 Spring 的設計原則是在 Bean 初始化完成之後才為其建立代理。是以,Spring 選擇了三級緩存。但是因為循環依賴的出現,導緻了 Spring 不得不提前去建立代理,因為如果不提前建立代理對象,那麼注入的就是原始對象,這樣就會産生錯誤。
參考https://www.jb51.net/article/197450.htm