你的位置:首页 > Java教程

[Java教程]Spring Bean的加载


Spring加载bean的原则:不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中。
 
单例bean在Spring容器里只会创建一次,后续创建爱时会首先从缓存中获取,尝试加载,不成功则从singletonFatories中加载。当存在循环依赖(原型模式发生,判断:isPrototypeCurrentlyInCreation(beanName))的时候,依据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();}

工厂方法配置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对应单例工厂。