如题,我所了解的循环依赖是通过三个哈希表来分别存储已初始化,已实例化但还未注入属性和初始化和进入实例化阶段的bean来解决的。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
//存放已实例化,但尚未填充属性和初始化的bean,我们称这类bean为早期引用。该二级缓存用于解决循环依赖
private final Map<String, Object> earlySingletonObjects = new HashMap(16);
//存放进入实例化阶段的Bean,主要作用是提前暴露这些bean
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
我对第三个哈希表存储的键值对有点不理解,它存储的键是beanName,那他存储的value是什么呢?
我在看了一下相关源码:
//doCreateBean方法的一部分
if (earlySingletonExposure) {
//...
//3.将创建完的bean添加到三级缓存
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
//如果bean不是AOP代理,则本方法直接返回bean。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var5 = this.getBeanPostProcessors().iterator();
while(var5.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var5.next();
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
//3-2将beanName-singletonFactory工厂作为映射添加到三级缓存里
this.singletonFactories.put(beanName, singletonFactory);
//3-3从二级缓存里移除beanName
this.earlySingletonObjects.remove(beanName);
//3-4在registeredSingletons里注册beanName
this.registeredSingletons.add(beanName);
}
}
}
觉得三级缓存存储的value值是RootBeanDefinition,我对这个类的理解是它存储的是Bean定义的信息,但它也是一个ObjectFactory?
不知道这么理解是否正确,希望有人指点一下?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…