什么是spring循环依赖?如何解决循环依赖?

156 阅读2分钟

1.什么是spring循环依赖

Spring 循环依赖是指两个或多个 Bean 相互依赖,形成一个循环引用的关系。例如,Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A.这样就形成了一个循环依赖。

2.如何解决循环依赖?

循环依赖在 Spring 中是一种常见的问题,可能会导致 Bean 的初始化失败或无法注入。为了解决循环依赖的问题,Spring 引入了三级缓存机制,在 Bean 的初始化过程中进行处理,以确保 Bean 的正确初始化和注入。

三级缓存主要包括以下三个缓存:

1、singletonobjects 一级缓存

一级缓存用于存储已经实例化的 Bean,当一个 Bean 被创建完成后,它会被添加到 singletonObjects 缓存中。 该缓存保证了在整个容器中只存在一个实例。

2、earlysingletonobjects 二级缓存

二级缓存用于存储提前暴露的 Bean 实例,即已完成实例化但未完成初始化的 Bean。当一个 Bean 在初始化过程中发现依赖了另一个已实例化但并未完成初始化的半成品 Bean 时,会将该未初始化的半成品 Bean 存储到earlySingletonObjects 缓存中。该缓存保证了在循环依赖的情况下也能完成 Bean 的初始化。

3、singletonFactories 三级缓存

三级缓步用于存储 Bean 工厂,即用于存储创建的 Bean 的 FactoryBean 实例。 当容器创建一个 Bean 时,会先将该 Bean 的ObjectFactory 存储到 singletonFactories 缓存中。

1722495041093.jpg

1722495193110.jpg

1、当容器创建一个 Bean 时,会先将该 Bean 的 ObjectFfactory 加入到 singletonFactories 三级缓存中,并设置一个占位符。
2、Spring 会调用该 Bean 的构造函数或工厂方法创建实例,并对实例进行依赖注入。
3、如果在依赖注入过程中,发现该 Bean 依赖另外一个未实例化的 Bean,会进入该被依赖的 Bean 的实例化流程。
4、如果被依赖的 Bean 在初始化时发现需要依较原始 Bean,那么会从 singletonfactories 三级缓存中获取原始 Bean,并将原始 Bean存储到 earvsimngletonobiects 二级缓存中,然后用它创建实例并注入被依赖的 Bean。
5、Sping 会继续设置属性和初始化被依赖的 Bean,被依赖的 Bean 初始化完成后会将其添加到 singletonObjects一级缓存中,并将其从 earysingletonobjects 二级缓存和singletonFactories 三级缓存中移除.
6、Sping 会继续设置属性和初始化原始 Bean,当该 Bean初始化完成后,Sping 会将其添加到 singletonObiects -级缓存中,并将其从 earsingletonobiects 二级绣存和singletonFactories 三级缓存中移除。