回答
Spring 中的三级缓存是一种用于解决循环依赖问题的机制,Spring 通过三级缓存,让尚未完全初始化的 Bean 也能够注入到其他 Bean 中,以此来打破循环依赖的问题。
在 Spring 中,有一级、二级、三级缓存:
- 一级缓存:也叫单例池,为最常用的缓存,用于存放已经完成初始化的单例 Bean。
- 二级缓存:为早期对象缓存,用于存放还没有完全初始化好的的 Bean 实例。当一个 Bean 实例已经实例化了但还没有完全初始化时(例如,还没有执行完
@PostConstruct
注解的方法或者实现了InitializingBean
接口的方法)时,它的实例会被放在这个缓存中。当其他的 Bean 需要依赖这个还没有完全完成初始化的 Bean 时,就可以直接从二级缓存中获取它的早期对象完成注入。 - 三级缓存:为单例工厂缓存,用于存放创建 Bean 实例的工厂对象。当一个 Bean 的实例需要被创建时,Spring 容器会先为该 Bean 对象创建一个工厂对象
ObjectFactory
,这个工厂对象负责生成 Bean 的实例。Spring 会将这个工厂对象放入到三级缓存中,当其他 Bean 实例需要依赖这个还没有被创建的 Bean 时,就可以直接从三级缓存中获取它的工厂对象。
Spring 的三级缓存是解决循环依赖的关键,关于循环依赖请阅读面试题:Spring是如何解决循依赖问题?
详解
下面举一个例子来阐述 Spring 是如何利用三级缓存的,假如我有 A
、B
、C
三个对象,他们定义如下:
@Service
public class A {
@Autowired
private B b;
}
@Service
public class B {
@Autowired
private C c;
}
@Service
public class C {
@Autowired
private A a;
}
在这个结构下,A
依赖 B
,B
依赖 C
,而 C
又依赖 A
,形成了一个完整的循环依赖闭环,我们来看看 Spring 是如何通过三级缓存来处理这个闭环的。