🔍在 Spring 框架中,循环依赖是指两个或多个 Bean 之间相互依赖,形成一个循环引用的情况。这种情况下,Spring IOC 容器在实例化 Bean 时可能会出现问题,因为它无法决定应该首先实例化哪个 Bean。为了解决这个问题,Spring 引入了三级缓存。
三级缓存是指 Spring IOC 容器中用于解决循环依赖问题的一种机制,它包含三个缓存阶段🔥:
- singletonObjects:这是 Spring IOC 容器的一级缓存,用于存储已经完全创建并初始化的 Bean实例。当 Bean 完全创建后,它会被放置在这个缓存中。
- earlySingletonObjects:这是 Spring IOC 容器的二级缓存,用于存储提前暴露的、尚未完全初始化的 Bean 实例。当 Bean 正在被创建但尚未完成初始化时,它会被放置在这个缓存中。
- singletonFactories:这是 Spring IOC 容器的三级缓存,用于存储 Bean 的工厂对象。在创建Bean 实例时,Spring 首先会在这个缓存中查找工厂对象,如果找到则使用该工厂对象来创建 Bean 实例。
✨三级缓存的作用是为了解决循环依赖时的初始化顺序问题。在初始化 Bean 时,Spring 会首先将 Bean 的实例放入三级缓存中,然后进行属性注入等操作。如果发现循环依赖,Spring 会在二级缓存中查找对应的 Bean 实例,如果找到则直接返回,否则会调用Bean的工厂方法来创建 Bean 实例,并将其放入二级缓存中。当 Bean 实例化完成后,会从二级缓存中移除,并放入一级缓存中。
为什么需要三级缓存而不是二级缓存?
二级缓存只存储了尚未初始化完成的 Bean 实例,而三级缓存存储了 Bean 的工厂对象。这样做的好处是,当发现循环依赖时,可以通过 Bean 的工厂对象来创建 Bean 实例,从而避免了直接从二级缓存中获取可能尚未完成初始化的 Bean 实例而导致的问题。因此,三级缓存提供了更加灵活和可靠的解决方案,能够更好地处理循环依赖问题。