Spring 如何解决循环依赖?
Spring通过三级缓存机制来解决单例Bean的Setter或字段注入类型的循环依赖问题。以下是Spring解决循环依赖的核心流程:
1. 三级缓存介绍
Spring容器为了解决循环依赖,维护了以下三个缓存:
- 一级缓存(singletonObjects):已完全初始化的单例Bean。
- 二级缓存(earlySingletonObjects):早期暴露的Bean(未完全初始化,但已注入必要属性)。
- 三级缓存(singletonFactories):存储创建Bean的工厂,允许获取Bean的代理对象。
2. 解决循环依赖的关键流程
以下是Spring处理循环依赖的步骤:
创建Bean实例:
Spring在实例化一个Bean时,首先会在一级缓存中查找。如果未找到,会尝试通过三级缓存提前暴露一个工厂,用于生成当前正在创建的Bean的早期引用。将早期引用暴露到三级缓存:
Spring在Bean实例化之后,尚未填充属性之前,会将Bean的ObjectFactory(一个创建Bean早期引用的工厂)存入三级缓存。填充依赖:
在填充Bean的依赖时,如果发现需要依赖另一个Bean且该Bean正在创建中,Spring会从三级缓存中获取早期引用,并注入到当前Bean中。完成初始化:
当Bean完成属性注入并经过初始化回调后,Spring会将完全初始化的Bean移入一级缓存,同时从二级和三级缓存中移除该Bean的引用。
3. 示例代码
以循环依赖为例:
@Component
public class BeanA {
@Autowired
private BeanB beanB;
}
@Component
public class BeanB {
@Autowired
private BeanA beanA;
}
Spring解决的流程:
- 初始化BeanA,发现依赖BeanB;
- 开始初始化BeanB,发现依赖BeanA;
- 从三级缓存中获取BeanA的早期引用,将其注入到BeanB;
- BeanB完成初始化,存入一级缓存;
- 返回继续完成BeanA的初始化。
4. 注意事项
仅适用于单例作用域:
Spring的三级缓存机制仅适用于单例Bean。Prototype作用域的Bean不受容器管理,无法提前暴露早期引用,因此无法解决循环依赖。构造器注入无法解决:
构造器注入要求在实例化时提供完整依赖,而此时无法提前暴露引用,Spring会直接抛出BeanCurrentlyInCreationException。
5. 如何避免循环依赖
虽然Spring能够解决部分循环依赖,但实际开发中,建议通过以下方式避免:
- 优化设计,拆分循环依赖。
- 使用@Lazy懒加载,延迟依赖的注入时机。
- 引入接口或事件机制,解耦Bean之间的直接依赖。
总结:
Spring通过三级缓存机制解决了Setter和字段注入的循环依赖问题,而构造器注入和Prototype作用域需要开发者自行设计规避。
Spring 如何解决循环依赖?的更多相关文章
- Spring 如何解决循环依赖问题?
在关于Spring的面试中,我们经常会被问到一个问题,就是Spring是如何解决循环依赖的问题的. 这个问题算是关于Spring的一个高频面试题,因为如果不刻意研读,相信即使读过源码,面试者也不一定能 ...
- Spring如何解决循环依赖问题
目录 1. 什么是循环依赖? 2. 怎么检测是否存在循环依赖 3. Spring怎么解决循环依赖 本文主要是分析Spring bean的循环依赖,以及Spring的解决方式. 通过这种解决方式,我们可 ...
- Spring 如何解决循环依赖的问题
Spring 如何解决循环依赖的问题 https://blog.csdn.net/qq_36381855/article/details/79752689 Spring IOC 容器源码分析 - 循环 ...
- 一张图彻底理解Spring如何解决循环依赖!!
写在前面 最近,在看Spring源码,看到Spring解决循环依赖问题的源码时,不得不说,源码写的太烂了.像Spring这种顶级的项目源码,竟然存在着这种xxx的代码.看了几次都有点头大,相信很多小伙 ...
- Spring如何解决循环依赖
一.什么是循环依赖 多个bean之间相互依赖,形成了一个闭环. 比如:A依赖于B.B依赖于c.c依赖于A 通常来说,如果问spring容器内部如何解决循环依赖, 一定是指默认的单例Bean中,属性互相 ...
- Spring中解决循环依赖报错的问题
什么是循环依赖 当一个ClassA依赖于ClassB,然后ClassB又反过来依赖ClassA,这就形成了一个循环依赖: ClassA -> ClassB -> ClassA 原创声明 本 ...
- Spring如何解决循环依赖,你真的懂了?
导读 前几天发表的文章SpringBoot多数据源动态切换和SpringBoot整合多数据源的巨坑中,提到了一个坑就是动态数据源添加@Primary接口就会造成循环依赖异常,如下图: 这个就是典型的构 ...
- Spring如何解决循环依赖?
介绍 先说一下什么是循环依赖,Spring在初始化A的时候需要注入B,而初始化B的时候需要注入A,在Spring启动后这2个Bean都要被初始化完成 Spring的循环依赖有两种场景 构造器的循环依赖 ...
- 彻底理解Spring如何解决循环依赖
Spring bean生命周期 可以简化为以下5步. 1.构建BeanDefinition 2.实例化 Instantiation 3.属性赋值 Populate 4.初始化 Initializati ...
- 【Spring】 Spring如何解决循环依赖的问题?
https://mp.weixin.qq.com/s/FtbzTMxHgzL0G1R2pSlh-A 通常来说,如果问Spring内部如何解决循环依赖,一定是单默认的单例Bean中,属性互相引用的场景. ...
随机推荐
- Solon Cloud Gateway 开发:导引
Solon Cloud Gateway 是 Solon Cloud 体系提供的分布式网关实现(轻量级实现). 分布式网关的特点(相对于本地网关): 提供服务路由能力 提供各种拦截支持 1.分布式网关推 ...
- 深入理解 Future, CompletableFuture, ListenableFuture,回调机制
深入理解 Future, CompletableFuture, ListenableFuture,回调机制 本文禁止转载. 本文从设计思想.具体实现等角度分析了 Future.CompletableF ...
- Zabbix Proxy安装及替换Zabbix阿里云源脚本
zabbix proxy安装步骤 说明: Zabbix Proxy使用的是独立的数据库实例,如果放在一起数据容易遭到破坏;Proxy仅仅是一个数据采集的作用,其他的依然是依靠Server端实现,这就会 ...
- 配置Slf4j
1.maven添加 <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api< ...
- 《Vue2 框架第二课:组件结构与模板语法详解》
写在开头:Vue.js 是一个流行的前端框架,广泛应用于构建用户界面和单页应用(SPA).然而,需要注意的是,Vue2 已经于 2023 年底 正式停止维护.这意味着官方团队将不再为 Vue2 提供功 ...
- 20 分钟高效掌握 cursor
本身属于在前端小组的一次小分享,这里做个同步分享. 一.pro 权益说明 目前公司购买了 2 个 pro 月付账号,权益包括无限制 tab 补全与 ai 聊天,但每个月只有 500 个快速请求权益,如 ...
- Normalizing flow 流模型 | CS236深度生成模型Lec8学习笔记
主要参考资料:Stanford University CS236: Deep Generative Models Lec8. 这篇blog基本上是CS236 Lec8的刷课总结/刷课笔记. VAE 这 ...
- 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!
引子:那个让运维集体加班的夜晚 "凡哥!线上服务响应时间飙到10秒了!"凌晨1点,实习生小李的语音带着哭腔. 监控大屏上,JVM堆内存曲线像坐了火箭--刚扩容的16G内存,30分钟 ...
- qa 工作
1.定流程--监控参照规范(cmmi,公司自己的,scrum[例会.启动会])--产出物报告 (项目维度)-配置--经盈.财务 2.培训组织-组织讲师(知识库).外部拓展
- wxpython SetValue 获取列表数据获取不到
self.m_textCtrl4.SetValue(files) 同样的方法获取其他值就获取到了 ,后来想了想files是列表数据,于是将类型变为str型成功 self.m_textCtrl4.Set ...