网站首页 > 博客文章 正文
Spring的循环依赖问题一直是中高级Java高频面试题之一,其中的考点就在于你对Spring中bean的加载过程是否有一定的理解。
那么我们就从以下几点说一下。
Spring中常用的注入方式有哪几种?
构造器注入
set方法注入
注解注入
关于这方面的知识之后再细聊,今天的重点不是这些。
什么是循环依赖?
循环依赖,注意,这里说的是依赖,而不是调用,这是两个概念,一定不要混淆。
循环依赖从字面意思来看,就是A依赖B,然后B依赖A,当然,这个依赖过程也可以更长,不一定就非要两个互相依赖,十个八个也是循环依赖,只要形成了一个闭环。
如图,这样就形成了一个闭环,简单说,如此依赖下去,就是一个死循环。
如何解决循环依赖?
Spring中的循环依赖包括两种,构造器循环依赖和setter循环依赖。
构造器循环依赖
当使用构造器注入方式时,Spring是无法解决循环依赖的,在出问题时会报错,抛出BeanCurrentlyInCreationException异常。
模拟一下场景的话,大概如下:
1. X1在创建时,发现构造器需要X2类对象,只能去创建X2;
2. X2在创建时,又发现构造器需要X3类对象,只能去创建X3;
3. X3在创建时,又再次发现构造器需要X1对象;周而复始,最终抛出异常。
setter循环依赖
主要来说一下setter循环依赖,通过Spring在创建bean时的一级、二级、三级缓存的概念解决的。
注意:这里解决的只是单例模式下的setter循环依赖,非单例模式下的依然没有办法解决,在业务环境中应当尽量避免此类情况。
创建Bean的缓存概念:
一级缓存:singletonObjects,可以称为成品池,存放完全实例化属性赋值完成的Bean,直接可以使用。
二级缓存:earlySingletonObjects,可以称为半成品池,存放早期Bean的引用,尚未属性装配的Bean
三级缓存:singletonFactories,可以称为工厂池,存放实例化完成的Bean工厂。
通过setter注入时,会经历以下几个过程。
看图说话!
1. X1在创建时,首先根据构造函数创建bean,暴露一个Factory给三级缓存(工厂池),并且将其放入二级缓存(半成品池);然后进行属性的装配,发现有依赖关系,查询三级缓存是否存在,如没有,前往创建。
2. 创建X2时,同X1,前往创建X3。
3. 创建X3时,这时三级缓存中已经存在X1,即可直接注入,然后将X3的bean对象放入一级缓存(成品池)。
4. 随后X2、X1依次可以创建完成,并且放入一级缓存中。
5. 如此就完成setter循环依赖问题的解决,核心就是这个三级缓存。
注意:这里的bean对象创建完成,放入一级缓存中时,会将对应的二级、三级缓存清掉。
猜你喜欢
- 2025-01-14 C#面试宝典 2022年 60个常见的C#面试问题和答案
- 2025-01-14 宝藏!2024年RAG面试问题及答案 TOP30(下)
- 2025-01-14 40道 Redis 运维面试题(附答案)
- 2025-01-14 SpringBoot 整合 Quartz 实现 JAVA 定时任务的动态配置
- 2025-01-14 10个Python面试的高级问题
- 2025-01-14 「干货」 redis面试题
- 2025-01-14 关于Java 工程师面试,这几个点注意了,offer拿到手软
- 2025-01-14 Java程序员面试自我介绍部分讲什么?面试技巧
- 2025-01-14 这358道大厂经典面试前端面试题,你会多少?
- 2025-01-14 读完这46道Redis面试题之后,你就会觉得自己的Redis白学了
你 发表评论:
欢迎- 最近发表
-
- 别再用雪花算法生成ID了!试试这个吧
- Cacti监控服务器配置教程(基于CentOS+Nginx+MySQL+PHP环境搭建)
- 业务系统性能问题诊断和优化分析(业务系统性能问题诊断和优化分析报告)
- 数据库中如何批量添加指定数据(数据库批量新增数据)
- Instagram架构的分片和ID的设计(ins的分类)
- VBA数据库解决方案第十四讲:如何在数据库中动态删除和建立数据表
- MySQL数据库安装教程(mysql数据库安装方法)
- SOLIDWORKS Electrical卸载与升级安装操作步骤
- 数据库分库分表解决方案汇总(数据库分库分表思路)
- 根据工作表数据生成数据库(根据excel生成数据库表结构)
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- googlecloud (64)
- flutterrun (59)
- 系统设计图 (58)
- powershellfor (73)
- messagesource (71)
- plsql64位 (73)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- qcombobox样式表 (68)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)