1、概述
spring中,存在A依赖B,同时B又依赖A的情况,这种情况下,spring如何进行bean初始化呢?
@Service
public class A {
@Autowired
private B b;
}
@Service
public class B {
@Autowired
private A a;
}
本文来解释这个问题。
2、spring的应对之道
2.1 三级缓存介绍
Spring 框架在解决单例 Bean 的循环依赖问题时,使用了三级缓存机制。这三级缓存分别是:
- 一级缓存(singletonObjects)
- 二级缓存(earlySingletonObjects)
- 三级缓存(singletonFactories)
每级缓存都有其特定的作用,下面详细解释这三级缓存的作用:
1. 一级缓存(singletonObjects)
作用:存储完全初始化好的 Bean 实例。
特点:当一个 Bean 完全初始化并准备好使用时,会被放入 singletonObjects 缓存中。
访问时机:当其他 Bean 需要依赖这个 Bean 时,会直接从 singletonObjects 中获取。
2. 二级缓存(earlySingletonObjects)
作用:存储部分初始化的 Bean 实例。
特点:当一个 Bean 正在创建过程中,但还没有完全初始化完毕时,会被放入 earlySingletonObjects 缓存中。
访问时机:当其他 Bean 需要依赖这个正在创建中的 Bean 时,会从 earlySingletonObjects 中获取部分初始化的实例。
3. 三级缓存(singletonFactories)
作用:存储创建 Bean 的工厂对象。
特点:当一个 Bean 正在创建过程中,Spring 会将创建这个 Bean 的工厂对象放入 singletonFactories 缓存中。
访问时机:当其他 Bean 需要依赖这个正在创建中的 Bean 时,会从 singletonFactories 中获取工厂对象,并通过工厂对象获取部分初始化的实例
2.2 bean初始化过程
上述创建过程中有一些疑问:
- 第三步的B依赖的是A1,A1是部分创建成功的,也就是B也是部分创建成功的,那为什么B能放在一级缓存中呢,放在一级缓存中意味着B是可以被使用的。
- 第四步:A创建后,A1的状态是什么样的?
- 第四步:B之前依赖的是A1,如何把依赖更新到A上的?