天天看點

圖解spring的bean建立的生命周期

注意:

  • 執行個體化是使用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