如果有遗漏,评论区告诉我进行补充
面试官: springboot如何处理循环依赖的问题?
我回答:
循环依赖的概念
当两个或多个 Bean 相互依赖对方,就形成了循环依赖。例如,Bean A 依赖 Bean B,同时 Bean B 又依赖 Bean A。这会导致应用程序无法正确地初始化和运行,因为Spring Boot无法处理这种循环依赖关系。
Spring Boot 处理循环依赖的机制
Spring容器在启动时,会扫描配置文件(如applicationContext.xml)或注解定义的Bean,并尝试创建这些Bean的实例。在这个过程中,Spring会跟踪哪些Bean正在被创建,以便检测循环依赖。Spring通过一个名为“DefaultSingletonBeanRegistry”的类来跟踪单例Bean的创建状态,并使用三个主要的缓存来管理Bean的创建过程:

java循环结构的基础题好难
三级缓存机制
- 一级缓存:singletonObjects
- 这是一个,用于存放完全初始化好的单例 Bean。当一个 Bean 完成创建和初始化(包括属性注入等所有步骤)后,就会被放入这个缓存中。
- 二级缓存:earlySingletonObjects
- 也是一个。当一个 Bean 正在创建过程中(还未完全初始化),但是已经被创建了实例(通过构造函数创建),就会被放入这个缓存。这个缓存主要是为了解决循环依赖中的半成品 Bean 的暴露问题。
- 三级缓存:singletonFactories
- 这是一个,存放的是对象。当一个 Bean 开始创建时,会将创建这个 Bean 的放入这个缓存。是一个函数式接口,它的作用是在需要的时候创建 Bean 实例。
创建过程中的循环依赖处理
- Bean A 的创建过程
- 当容器开始创建 Bean A 时,首先会将 Bean A 的创建工厂()放入三级缓存。
- 然后进行 Bean A 的实例化,通过构造函数创建出 Bean A 的实例,但此时 Bean A 还未完成属性注入等初始化操作。
- 当进行 Bean A 的属性注入时,发现依赖 Bean B。
- Bean B 的创建过程
- 容器开始创建 Bean B,同样先将 Bean B 的创建工厂放入三级缓存。
- 实例化 Bean B,在对 Bean B 进行属性注入时发现依赖 Bean A。
- 此时容器会在三级缓存中查找 Bean A 的创建工厂,通过这个工厂得到 Bean A 的早期实例(半成品实例,还未完全初始化),将这个早期实例放入二级缓存,并从三级缓存中移除 Bean A 的创建工厂。
- Bean B 完成属性注入(其中包含了注入 Bean A 的早期实例)和其他初始化操作,成为一个完全初始化的 Bean,放入一级缓存。
- Bean A 继续创建过程
- 由于 Bean B 已经完成创建并注入到 Bean A 中,Bean A 可以继续完成自己的属性注入(此时注入的 Bean B 是完全初始化的)和其他初始化操作,成为一个完全初始化的 Bean,放入一级缓存。
示例代码说明
以下是一个简单的示例代码来演示循环依赖的情况:
讯享网在上述代码中,依赖,又依赖。通过 Spring Boot 的循环依赖处理机制,即使存在这种循环依赖关系,也能够正确地创建和初始化这两个 Bean。
需要注意的是,虽然 Spring Boot 能够处理循环依赖,但循环依赖通常是一种不良的设计模式,可能会导致代码难以理解和维护,在实际开发中应尽量避免。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/301.html