概述
- createBeanInstance:实例化,其实就是 调用对象的构造方法实例化对象。
- populateBean:填充属性,这一步主要是多bean的依赖属性进行填充。
- initializeBean:调用spring xml中的init() 方法,或者@PostConstruct注解的init()方法。
三级缓存
对于单例来说,在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拿到对象。
单例初始流程
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/100357.html