A依赖B B依赖A的场景
public class A {
private B b;
public void setB(B b) {
this.b = b;
}
@Override
public String toString() {
return "A::toString";
}
}
public class B {
private A a;
public void setA(A a) {
this.a = a;
}
@Override
public String toString() {
return "B::toString";
}
}
xml 配置
<bean id="a" class="com.xiya.test.cricle.A">
<property name="b" ref="b"/>
</bean>
<bean id="b" class="com.xiya.test.cricle.B">
<property name="a" ref="a"/>
</bean>
解决循环依赖的3个缓存
// org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
// 单例对象工厂的cache
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 提前暴光的单例对象的Cache
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
// 单例对象工厂的cache
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
// 标识那个实例在创建中,判断是否存在循环依赖
private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String) ->
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
所有的 getBean 都指向了 doGetBean 方法
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
getBean(“a”): 第一次查a
- 执行 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String) 返回 null
singletonObjects earlySingletonObjects singletonFactories 都为空 - 执行 sharedInstance = getSingleton(beanName, () -> {try { return createBean(beanName, mbd, args);}catch (BeansException ex) {destroySingleton(beanName);throw ex;}});
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
3. 执行 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#beforeSingletonCreation 将实例a放入singletonsCurrentlyInCreation,表示a正在创建中
4. 执行 singletonFactory.getObject() 回调 getSingleton 方法的第二个参数 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
最终执行的 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
5. 执行 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance 此时a实例被创建出来(属性还没有设置)
6. 执行 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
将实例a放入singletonFactories,singletonObjects earlySingletonObjects此时都为空
7. 执行 populateBean(beanName, mbd, instanceWrapper) 方法,设置a实例的属性
一系列无关操作过后最终还是执行 doGetBean 方法,获取b实例
org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveValueIfNecessary ->
org.springframework.beans.factory.support.BeanDefinitionValueResolver#resolveReference ->
最终执行 this.beanFactory.getBean(resolvedName)
执行完上述 getBean(“a”)
singletonFactories/singletonsCurrentlyInCreation包含a,singletonObjects earlySingletonObjects此时都为空
getBean(“b”): 第一次查b
8. 执行上述 1. 2.
9. 执行3.后singletonFactories包含a,singletonsCurrentlyInCreation包含a和b,singletonObjects earlySingletonObjects此时都为空
10. 执行上述 3. 4.
11. 执行5.后,b实例创建出来
12. 执行6.后,singletonFactories包含a和b,singletonsCurrentlyInCreation包含a和b,singletonObjects earlySingletonObjects此时都为空
13. 执行7. 因为 b依赖a,接着又去执行 doGetBean 方法,获取a实例
getBean(“a”): 第二次查a
14. 执行1.从 singletonFactories 三级缓存获取a实例,将其删除并放入二级缓存earlySingletonObjects
此时 singletonFactories只包含b,earlySingletonObjects包含a,singletonsCurrentlyInCreation包含a和b,singletonObjects 为空
getBean(“a”) 成功返回 a 实例
- 接着执行13.populateBean b 的属性a就注入进来了
- 执行 initializeBean(beanName, exposedObject, mbd) 初始化 b 实例
- 接着执行10.
- 执行 afterSingletonCreation(beanName) singletonsCurrentlyInCreation删除b实例,此时 singletonFactories只包含b,earlySingletonObjects包含a,singletonsCurrentlyInCreation只包含a,singletonObjects 为空
- 执行 addSingleton(beanName, singletonObject) singletonObjects放b实例,singletonFactories删除b实例
- 此时 singletonFactories为空,earlySingletonObjects只包含a,singletonsCurrentlyInCreation只包含a,singletonObjects只包含b
- getBean(“b”) 执行完
- 接着执行7. a的实例b就注入进来了
- 执行 initializeBean(beanName, exposedObject, mbd) 初始化 a 实例
- 接着执行4.
- 执行 afterSingletonCreation(beanName) singletonsCurrentlyInCreation删除a实例
- 此时 singletonFactories为空,earlySingletonObjects只包含a,singletonsCurrentlyInCreation为空,singletonObjects只包含b
- 执行 addSingleton(beanName, singletonObject),singletonObjects 放入 a实例,earlySingletonObjects删除a实例
- 此时 singletonFactories earlySingletonObjects singletonsCurrentlyInCreation为空,singletonObjects包含a和b
- getBean(“a”) 执行完
这样看,二级缓存就可以解决循环依赖,为什么还需要多一级缓存?
再看a依赖b,a依赖c,b依赖a,c依赖a
假设只有 singletonFactories singletonObjects 二级缓存
getBean(“a”) a 放到 singletonFactories
getBean(“b”) b 放到 singletonFactories
getBean(“a”) 生成a实例,设置b的属性a,b实例化完成
getBean(“c”) c 放到 singletonFactories
getBean(“a”) 生成a实例,设置c的属性a,c实例化完成
这样导致a被生成了两次,不再是单例。