Spring Bean的載入,SpringBean載入
Spring載入bean的原則:不等bean建立完成就會將建立bean的ObjectFactory提早曝光加入到緩衝中。 單例bean在Spring容器裡只會建立一次,後續建立時會首先從緩衝中擷取,嘗試載入,不成功則從singletonFatories中載入。當存在循環相依性的時候,依據Spring的載入bean原則,下一個bean需要依賴上一個bean的時候直接使用ObjectFactory。 緩衝中儲存的是bean的原始狀態,需要進行bean的執行個體化操作。 Spring初始化bean的時候,會首先初始化這個bean所對應的依賴。
package org.springframework.beans.factory;/*** Interface to be implemented by objects used within a {@link BeanFactory}* which are themselves factories. If a bean implements this interface,* it is used as a factory for an object to expose, not directly as a bean* instance that will be exposed itself.*/public interface FactoryBean<T> { /** * Return an instance (possibly shared or independent) of the object * managed by this factory. */ T getObject() throws Exception; /** * Return the type of object that this FactoryBean creates, * or {@code null} if not known in advance. */ Class<?> getObjectType(); /** * Is the object managed by this factory a singleton? That is, * will {@link #getObject()} always return the same object * (a reference that can be cached)? * 單例對象會放在Spring單例緩衝池中 */ boolean isSingleton();}
Factory 方法配置bean如下:
<bean id="book" class="com.xxx.model.BookFactory"/>
BookFactory實現了FactoryBean,則當使用getBean("book")時,返回FactoryBean#getObject()方法返回的對象,即FactoryBean#getObject()代理了getBean()方法:
Book book = ctx.getBean("book");
如果要擷取BookFactoryBean對象,則需要使用首碼“&”,使用如下:
BookFactory bookFactory = ctx.getBean("&book");
單例Bean(singleton)擷取步驟:
singletonObjects<BeanName, BeanInstance>.get(beanName):Map單例緩衝擷取。synchronized(this.singletonObjects),全域變數同步。 ↓↓ ↓↓==Null ↓↓
earlySingletonObjects<BeanName, BeanInstance> .get(beanName):處理循環參考依賴檢測。 ↓↓ ↓↓==Null ↓↓
singletonFactories<BeanName, BeanFactory> .get(beanName):調用
相應單例建立工廠getObject()返回Bean對象。 ↓↓ -->earlySingletonObjects.put(beanName, singletonObject)儲存擷取的Bean執行個體。 --> singletonFactories.remove(beanName)移除beanName對應單例工廠。
Bean建立:
Bean初始化:Aware方法,Post處理,Init處理。