解决循环依赖
一般都是通过属性注入解决循环依赖,简单来说就是先创建对象A,然后在为对象设置属性B,在初始化B时当发生循环依赖时,可以使用未完全初始化的对象A设置到B的属性。所以一个简单的实现就是将创建的半成品A先保存在缓存中,然后B依赖A时先使用缓存中的半成品A进行初始化,B正常初始化并注入到bean容器中。接着A也可以完成初始化也被加入到bean容器中并删除缓存的半成品。如果把bean容器也看做成功初始化bean的缓存,那么上面这个解决循环依赖的方案就是用了二级缓存。
AOP对循环依赖的影响
Spring中可能需要为类生产代理对象,一般情况下Spring都是在bean创建完成之后才创建代理对象,而在上面的方案中半成品A需要被提前注入到对象B中,这时应该生成A的代理对象然后将其作为属性注入到B中。生成代理的时机有两种:
- 对所有类都提前创建代理对象并放入缓存。
- 在发生循环依赖时创建代理对象。
Spring选择了后者,为了防止重复创建代理对象,将发生循环依赖的代理对象放入到一个缓存中,也就是earlySingletonObjects
中,在A对象完成初始化之后在earlySingletonObjects
中找到生成好的代理对象即可。Spring
在这里引入了earlySingletonObjects
作为代理对象的缓存,也就形成了Spring的三级缓存结构。
- 因循环依赖而需要提前使用的半成品缓存。
- 半成品的代理对象缓存。
- 最终完成初始化的bean缓存
Bean在缓存中流转过程
-
AbstractBeanFactory
中根据beanName
查找缓存的bean,如果没有创建则先创建,然后添加到缓存中。protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { String beanName = transformedBeanName(name); Object bean; // 在缓存根据beanName查找创建完成的bean,如果产生循环依赖(singletonFactory中有半成品对象A),则对其代理后加入代理对象缓存中并返回。 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { return createBean(beanName, mbd, args); }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } } return (T) bean; } protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { // 从半成品缓存中拿出包装好的对象A,这里通过之前传入的工厂方法获得代理对象。 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
-
DefaultSingletonBeanRegistry
使用工厂方法创建bean,并将bean添加到bean容器的缓存中。public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { // 工厂方法调用AbstractAutowireCapableBeanFactory创建bean singletonObject = singletonFactory.getObject(); newSingleton = true; if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { // 将创建完成的对象加入bean容器缓存中,并释放其他缓存 this.singletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } }
-
AbstractAutowireCapableBeanFactory
创建bean处理循环依赖,创建循环依赖的代理对象。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
Object bean = instanceWrapper.getWrappedInstance(); // 创建原始bean对象A
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 将原始bean对象A,加入缓存,这里对bean进行了一个包装,用于之后生成代理对象
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 省略初始化对象A的代码
// 对象A初始化完成
Object exposedObject = bean;
// 在代理对象缓存中取出已经生成的代理对象,并进行判断防止重复代理
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
}
return exposedObject;
}