排行
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
中国数据库
向量数据库
时序数据库
实时数据库
搜索引擎
空间数据库
图数据库
数据仓库
大调查
2021年报告
2022年报告
年度数据库
2020年openGauss
2021年TiDB
2022年PolarDB
2023年OceanBase
首页
资讯
活动
大会
学习
课程中心
推荐优质内容、热门课程
学习路径
预设学习计划、达成学习目标
知识图谱
综合了解技术体系知识点
课程库
快速筛选、搜索相关课程
视频学习
专业视频分享技术知识
电子文档
快速搜索阅览技术文档
文档
问答
服务
智能助手小墨
关于数据库相关的问题,您都可以问我
数据库巡检平台
脚本采集百余项,在线智能分析总结
SQLRUN
在线数据库即时SQL运行平台
数据库实训平台
实操环境、开箱即用、一键连接
数据库管理服务
汇聚顶级数据库专家,具备多数据库运维能力
数据库百科
核心案例
行业报告
月度解读
大事记
产业图谱
我的订单
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
资讯
活动
大会
课程
文档
排行
问答
我的订单
首页
专家团队
智能助手
在线工具
SQLRUN
在线数据库即时SQL运行平台
数据库在线实训平台
实操环境、开箱即用、一键连接
AWR分析
上传AWR报告,查看分析结果
SQL格式化
快速格式化绝大多数SQL语句
SQL审核
审核编写规范,提升执行效率
PLSQL解密
解密超4000字符的PL/SQL语句
OraC函数
查询Oracle C 函数的详细描述
智能助手小墨
关于数据库相关的问题,您都可以问我
精选案例
新闻资讯
云市场
登录后可立即获得以下权益
免费培训课程
收藏优质文章
疑难问题解答
下载专业文档
签到免费抽奖
提升成长等级
立即登录
登录
注册
登录
注册
首页
专家团队
智能助手
精选案例
新闻资讯
云市场
微信扫码
复制链接
新浪微博
分享数说
采集到收藏夹
分享到数说
举报
首页
/
高频面试题-说清楚Spring如何解决循环依赖?
高频面试题-说清楚Spring如何解决循环依赖?
Ijiran的编程思维
2021-06-14
783
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对象创建完成,放入一级缓存中时,会将对应的二级、三级缓存清掉。
面试
文章转载自
Ijiran的编程思维
,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
领墨值
有奖问卷
意见反馈
客服小墨