一、问题重现
情况一
SelfDependencyBean
中含有 SelfDependencyBean
属性并且需要依赖注入。
情况二
OrderServiceImpl
中含有 UserServiceImpl
属性并且需要依赖注入;
UserServiceImpl
中含有 OrderServiceImpl
属性并且需要依赖注入。
反正嘛,就是形成了循环的依赖关系就是这个意思。
如果单例的情况,Spring会自动帮你解决;而多例的情况,从逻辑上是会造成无限递归导致内存溢出,所以spring并不会帮你擦屁股哦。
二、知识预热
1. Spring容器中使用到的集合
- Set< String>
singletonsCurrentlyInCreation
:准备初始化的对象 - Map<String, Object>
singletonObjects
:已实例化+赋值完成对象 - Map<String, Object>
earlySingletonObjects
:早期对象(仅完成了实例化的对象) - Map<String, ObjectFactory<?>>
singletonFactories
:bean实例化的工厂类
2. 核心代码解析(节选+伪代码)
备注
>>>
是调用的意思->
是lambda表达式
DefaultListableBeanFactory
// 对象注册bean入口
getBean(beanName) >>> doGetBean(name, null, null, false) {
getSingleton(beanName)
getSingleton(beanName, () -> createBean(beanName, mbd, args))
}
AbstractBeanFactory
// 从缓存、早期对象、objectFactory集合中获取Bean对象
getSingleton(beanName, true)
// 标记当前bean对象的状态存入到集合中,并完成创建赋值
getSingleton(beanName, () -> createBean(beanName, mbd, args)) {
// 标记当前bean为初始化状态
beforeSingletonCreation(beanName)
// 创建对象,并且完成属性赋值
singletonObject = singletonFactory.getObject() -> createBean(beanName, mbd, args)
// 移除当前bean的初始化状态
afterSingletonCreation(beanName)
// 加入缓存
addSingleton(beanName, singletonObject)
}
AbstractAutowireCapableBeanFactory
// 创建对象,并且完成属性赋值
createBean(beanName, mbd, args) >>> doCreateBean(beanName, mbdToUse, args) {
// 使用反射技术,实例化对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 当前类是单例 && 允许循环依赖 && 当前bean为初始化状态
if (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)){
// 当前bean的工厂类加到准备实例化的objectFactory集合中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
}
// 属性赋值
populateBean(beanName, mbd, instanceWrapper);
// 执行bean的各种init方法+执行前后置处理器
exposedObject = initializeBean(beanName, exposedObject, mbd);
return instanceWrapper;
}
// 当前bean的工厂类加到准备实例化的objectFactory集合中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean))
// 属性赋值
populateBean(beanName, mbd, instanceWrapper) {
...
getBean(beanName)
...
}
简单粗暴集成Spring递归调用getBean方法—— 执行过程
getBean(OrderServiceImpl) >>> doGetBean(OrderServiceImpl, null, null, false) {
getSingleton(OrderServiceImpl) == null
getSingleton(OrderServiceImpl, () -> createBean(OrderServiceImpl, mbd, args)) {
// 标记 OrderServiceImpl 为初始化状态
beforeSingletonCreation(OrderServiceImpl)
// 创建对象,并且完成属性赋值
singletonObject = singletonFactory.getObject() -> createBean(OrderServiceImpl, mbd, args) >>> doCreateBean(OrderServiceImpl, mbdToUse, args) {
// 使用反射技术,实例化对象
instanceWrapper = createBeanInstance(OrderServiceImpl, mbd, args);
// OrderServiceImpl 是单例 && 允许循环依赖 && 当前bean为初始化状态
if (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(OrderServiceImpl)){
// OrderServiceImpl 工厂类加到准备实例化的objectFactory集合中
addSingletonFactory(OrderServiceImpl, () -> getEarlyBeanReference(OrderServiceImpl, mbd, bean))
}
// 属性赋值
populateBean(OrderServiceImpl, mbd, instanceWrapper) >>> ... >>> getBean(UserServiceImpl) >>> doGetBean(UserServiceImpl, null, null, false) {
getSingleton(UserServiceImpl) == null
getSingleton(UserServiceImpl, () -> createBean(UserServiceImpl, mbd, args)) {
// 标记 UserServiceImpl 为初始化状态
beforeSingletonCreation(UserServiceImpl)
// 创建对象,并且完成属性赋值
singletonObject = singletonFactory.getObject() -> createBean(UserServiceImpl, mbd, args) >>> doCreateBean(UserServiceImpl, mbdToUse, args) {
// 使用反射技术,实例化 UserServiceImpl
instanceWrapper2 = createBeanInstance(UserServiceImpl, mbd, args);
// UserServiceImpl 是单例 && 允许循环依赖 && 当前bean为初始化状态
if (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(UserServiceImpl)){
// UserServiceImpl 工厂类加到准备实例化的objectFactory集合中
addSingletonFactory(UserServiceImpl, () -> getEarlyBeanReference(UserServiceImpl, mbd, bean))
}
// 属性赋值
populateBean(UserServiceImpl, mbd, instanceWrapper2) >>> ... >>> getBean(OrderServiceImpl) >>> doGetBean(OrderServiceImpl, null, null, false) {
getSingleton(OrderServiceImpl) == OrderServiceImpl
}
// 执行bean的各种init方法+执行前后置处理器
exposedObject = initializeBean(UserServiceImpl, exposedObject, mbd);
return instanceWrapper2;
}
// 移除当前bean的初始化状态
afterSingletonCreation(beanName)
// 加入缓存
addSingleton(beanName, singletonObject)
}
}
// 执行bean的各种init方法+执行前后置处理器
exposedObject = initializeBean(OrderServiceImpl, exposedObject, mbd);
return instanceWrapper;
}
// 移除当前bean的初始化状态
afterSingletonCreation(beanName)
// 加入缓存
addSingleton(beanName, singletonObject)
}
}
其实Spring的内部是形成了递归调用的循环算法。就是getBean()
方法中,执行各种操作之后,又走回getBean()
方法。
为什么需要使用三级Map缓存解决循环依赖问题
讲道理只需要2层既可以解决循环依赖的问题了
- 标记当前bean正在初始化(用
singletonsCurrentlyInCreation
) - 第一层map(singletonObjects)获取完全体的bean?没有继续执行
- 第二层map(earlySingletonObjects)获取仅初始化bean?没有继续执行
- 直接将实例放进二级map,并返回实例
需要使用三级Map singletonFactories
的场景是为了解决AOP对象注入到容器中的bean是代理类,而不是当前对象
https://my.oschina.net/u/4340310/blog/4332450