以下讲的循环依赖时基于单例模式下的@Autowired或者set方法的spring的循环依赖
spring循环依赖 搞懂之前需要了解bean的创建过程
大概步骤如下:
1、org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String, Class
2、org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(String)
单例池中获取bean对象,第一次创建bean的时候肯定返回空
循环依赖发生时 进入该方法时候会从三级缓存singletonFactories中执行lambda表达式 生成代理对象,并且放置到二级缓存中
该方法里面个set集合 singletonsCurrentlyInCreation注意下面会设置值
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);//从一级缓存中获取
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//isSingletonCurrentlyInCreation 是从一个set中获取 意思是正在创建的对象 当你bean开始创建的时候就会设置进入这个set
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();//执行lambda表达式 提前aop
this.earlySingletonObjects.put(beanName, singletonObject);//放入二级缓存
this.singletonFactories.remove(beanName);//从三级缓存中移除
}
}
}
}
return singletonObject;
}
3、org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(String, ObjectFactory>) 这个方法第二个参数是个lambda表达式 只有真正调用getObject时候才会执行
注意此getSingleton 并非步骤2中的getSingleton 参数不一样
这个方法里面会做如下几件事情:
3.1.、beforeSingletonCreation 也就是会往singletonsCurrentlyInCreation这个set中放入该bean,代表bean正在创建中
3.2、 singletonFactory.getObject 真正执行lambda表达式 也就是执行下面这个方法 org.springframework.beans.factory.support.AbstractBeanFactory.createBean(String, RootBeanDefinition, Object[])
实现类在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])
真正实现bean的生命周期的方法是
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String, RootBeanDefinition, Object[])
3.2.1 、createBeanInstance 推断构造方法 实例化
3.2.2、addSingletonFactory 将该bean设置到三级缓存singletonFactories中去
3.2.3、populateBean 属性填充 当通过@Autowired或者set方法注入的时候 会在这个步骤里面填充属性 并且发现循环引用 重新调用步骤2
3.2.4、initializeBean 初始化bean
举例说明 如下代码块 A→B B→A 发生了循环引用
@Component
public class A {
@Autowired
B b;
}
@Component
public class B {
@Autowired
A a;
}
子方法 | 操作 | 三级缓存内容 | |
doGetBean | getSingleton(String) | 第一次来单例池找a 但找不到 | singletonFactories:无 earlySingletonObjects:无 singletonObjects:无 |
createBeanInstance | 实例化a | singletonFactories:无 earlySingletonObjects:无 singletonObjects:无 |
|
addSingletonFactory | a放入三级缓存 | singletonFactories:a earlySingletonObjects:无 singletonObjects:无 |
|
populateBean | postProcessProperties | 填充属性 发现b | singletonFactories:a earlySingletonObjects:无 singletonObjects:无 |
inject | 注入属性b | ||
doResolveDependency | 处理依赖 | ||
4.3 resolveCandidate | 等待getBean(b)的返回 | ||
beanFactory.getBean | get b的bean又回到第一步 | ||
doGetBean | getSingleton(String) | 获取b的bean 还是拿不到 | singletonFactories:a earlySingletonObjects:无 singletonObjects:无 |
createBeanInstance | 实例化b | singletonFactories:a earlySingletonObjects:无 singletonObjects:无 |
|
addSingletonFactory | b放入三级缓存 | singletonFactories:a、b earlySingletonObjects:无 singletonObjects:无 |
|
populateBean | postProcessProperties | 填充属性 发现a | singletonFactories:a、b earlySingletonObjects:无 singletonObjects:无 |
inject | 注入属性a | ||
doResolveDependency | 处理依赖 | ||
8.3resolveCandidate | 等待getBean(a)的返回 | ||
beanFactory.getBean | get a的bean又回到第一步 | ||
doGetBean | getSingleton(String) | 第二次来单例池找a 找到了并且执行getObject 提前aop了 | singletonFactories:b earlySingletonObjects:a singletonObjects:无 |
返回8.3resolveCandidate | 8.3方法resolveCandidate 获取到了返回的bean a 填充了 a属性 继续初始化b | singletonFactories:b earlySingletonObjects:a singletonObjects:无 |
|
initializeBean | 继续初始化b | singletonFactories:b earlySingletonObjects:a singletonObjects:无 |
|
getSingleton(String beanName, ObjectFactory> singletonFactory) | addSingleton(String beanName, Object singletonObject) | b初始化完成之后 添加到一级缓存 删除二级三级缓存 | singletonFactories:无 earlySingletonObjects:a singletonObjects:b |
返回4.3resolveCandidate | 返回完整的b对象给 给a来填充属性 | singletonFactories:无 earlySingletonObjects:a singletonObjects:b |
|
initializeBean | 初始化a | singletonFactories:无 earlySingletonObjects:a singletonObjects:b |
|
getSingleton(String beanName, ObjectFactory> singletonFactory) | addSingleton(String beanName, Object singletonObject) | a初始化完成之后 添加到一级缓存 删除二级三级缓存 | singletonFactories:无 earlySingletonObjects:无 singletonObjects:b、a |