目录
- 一、什么是循环依赖
- 二、循环依赖的Demo
- 三、Spring解决循环依赖的源码分析
- getBean(beanName)
- doGetBean(name, null, null, false)
- getSingleton(beanName)
- createBean(beanName, mbd, args)
- doCreateBean(beanName, mbdToUse, args)
- populateBean(beanName, mbd, instanceWrapper)
- applyPropertyValues(beanName, mbd, bw, pvs)
- valueResolver.resolveValueIfNecessary(pv, originalValue)
- resolveReference(argName, ref)
一、什么是循环依赖
Spring中的bean存在循环嵌套依赖的情况就叫做循环依赖
如下图:
- 情况一:A依赖着B,B也依赖着A,这是循环依赖
- 情况二:A依赖着B,B也依赖着C,C依赖着A,这是循环依赖
二、循环依赖的Demo
三、Spring解决循环依赖的源码分析
Spring循环依赖出现在创建bean时,首先调用AbstractBeanFactory#getBean()方法获取bean
getBean(beanName)
doGetBean(name, null, null, false)
getSingleton(beanName)
createBean(beanName, mbd, args)
doCreateBean(beanName, mbdToUse, args)
populateBean(beanName, mbd, instanceWrapper)
applyPropertyValues(beanName, mbd, bw, pvs)
valueResolver.resolveValueIfNecessary(pv, originalValue)
resolveReference(argName, ref)
调用getBean()
方法又回到了开头的getBean(beanName)
,此时去实例化B,实例化B的时候一步执行刚才实例bean A的步骤,然后到了调用populateBean(beanName, mbd, instanceWrapper)
方法注入bean A,又回到第二次实例化bean A,在调用getSingleton(beanName)
方法尝试从三级缓存中获取bean实例时,从第三级缓存singletonFactories
中获取到正在创建的bean A,这样就获取到bean A了,然后返回给bean B注入到bean B的属性中,完成bean B的初始化了,最后返回给bean A注入到bean A的属性中,这样就完成了循环依赖了。初始化bean A和bean B的流程图如下: