概述
Spring的单例对象的初始化主要分为三步。
- createBeanInstance:实例化,其实就是 调用对象的构造方法实例化对象。
- populateBean:填充属性,这一步主要是多bean的依赖属性进行填充。
- initializeBean:调用spring xml中的init() 方法,或者@PostConstruct注解的init()方法。
初始化Bean的先后顺序
1、bean实例化;
2、populateBean填充属性;
3、BeanPostProcessor的postProcessBeforeInitialization方法;
4、注解了@PostConstruct的方法;
5、InitializingBean的afterPropertiesSet方法;
6、bean的指定初始化方法:init-method;
6、BeanPostProcessor的postProcessAfterInitialization方法;
三级缓存
对于单例来说,在Spring容器整个生命周期内,有且只有一个对象,所以很容易想到这个对象应该存在Cache中,Spring为了解决单例的循环依赖问题,使用了三级缓存。
哪三级缓存
/** Cache of singleton objects: bean name --> bean instance */
// 一级缓存,完全初始化好的单例放入其中,从上下文获取的单例就是从这里获取
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);
/** Cache of singleton factories: bean name --> ObjectFactory */
// 三级缓存,存放实例化的对象,还没有对其进行属性填充
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
/** Cache of early singleton objects: bean name --> bean instance */
// 二级缓存,提前暴光的单例对象的Cache(用于检测循环引用,与singletonFactories互斥,就是要么在singletonFactories中要么在earlySingletonObjects中),
// 也只是实例化,但还没有填充属性
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
从缓存中获取bean
在获取bean的时候,首先是根据beanName从缓存中获取bean,如果获取不到就通过单列工厂创建,具体的流程可以看单列初始化流程图。
缓存中获取bean的逻辑是先从singletonObjects(一级缓存)获取,如果获取不到去earlySingletonObjects(二级缓存)获取,还是获取不到就从singletonFactories(三级缓存)获取。
源码如下:
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
synchronized(this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject != NULL_OBJECT ? singletonObject : null;
}
注释
- isSingletonCurrentlyInCreation()判断当前单例bean是否正在创建中,
也就是没有初始化完成(比如A的构造器依赖了B对象所以得先去创建B对象,
或则在A的populateBean过程中依赖了B对象,得先去创建B对象,这时的A就是处于创建中的状态。)- allowEarlyReference 是否允许从singletonFactories中通过getObject拿到对象。
单例初始流程