对Spring循环依赖的一些理解

news2024/11/25 10:36:50

什么是循环依赖

spring相互依赖怎么解决 被问到Spring循环依赖怎么解决 秀给面试官看 内附图解...

 类A有个字段需要注入类B,类B有个字段需要注入类C,类C有个字段需要注入类A,它们之间的依赖关系形成了一个循环。

Spring初始化完一个对象之后会把实例放入单例池(singletonObjects)中,也就是一级缓存。

我们看看一级缓存下循环依赖造成的结果。

1、new A(),发现需要B对象

2、去singletonObjects找B对象,没有找到

3、new B(),发现需要C对象

4、去singletonObjects找C对象,没有找到

5、new C(),发现需要A对象

6、去singletonObjects找A对象,没有找到

然后回到第一步,发现这个是死循环,最后会因为堆栈溢出而结束运行,所以一级缓存无法解决循环依赖问题。

循环依赖怎么解决

再新增一级缓存,把对象提前暴露出来(对象实例化但未初始化),新增一级的缓存叫earlySingletonObjects。

1、new A(),放入earlySingletonObjects, 发现需要B对象

2、去singletonObjects找B对象,没有找到

3、去earlySingletonObjects找B对象,没有找到

4、new B(),放入earlySingletonObjects,发现需要C对象

5、去singletonObjects找C对象,没有找到

6、去earlySingletonObjects找C对象,没有找到

7、new C(),放入earlySingletonObjects,发现需要A对象

8、去singletonObjects找A对象,没有找到

9、去earlySingletonObjects找A对象,找到了

10、给C对象的字段注入A对象,C对象初始化完成,把C对象放入singletonObjects

11、返回B对象的创建中,在singletonObjects找到C对象

12、给B对象的字段注入C对象,B对象初始化完成,把B对象放入singletonObjects

13、返回A对象的创建中,在singletonObjects找到B对象

14、给A对象的字段注入B对象,A对象初始化完成,把A对象放入singletonObjects

15、END

二级缓存就可以解决循坏依赖的问题了。

Spring为什么使用三级缓存解决循环依赖

但Spring为什么还用三级缓存去解决呢?

因为二级缓存虽然解决了循环依赖,但是还有AOP的问题没有解决。

如果一个Bean需要被代理,那么它在初始化完成之后原始Bean会被代理Bean替换掉放入IOC容器,其他Bean注入的也是代理对象,如果使用上述二级缓存的流程,那么其他对象注入的都是原始对象,AOP就失效了。

如果使用上述的二级缓存,还有一个方法可以解决AOP失效,就是提前AOP,这样earlySingletonObjects放的就是代理对象了。但是有个问题,你在实例化A的时候,你根本不知道A产生了循环依赖,你只有到了实例化C,为C注入属性的时候才能知道A产生了循环依赖。如果我们可以提前知道A没有循环依赖,我们就可以不用提前AOP(没有循环依赖也就是不用提前暴露bean,其他bean也就不会提前拿到并注入),A走正常流程就可以了。现在问题是我们不能提前知道循环依赖,所以只能无差别的对Bean提前进行AOP。

这是一个解决方案,但不是一个好方案,因为AOP的流程被提前了,相当于Bean的生命周期改变了,Bean的生命周期在整个Spring框架中是核心、底层的东西。这个方案相当于架构为问题让步、妥协,我们知道架构这东西一旦定下来就很少再改了,除非迫不得已,否则底层的东西不会向问题让步,最不济也是选一个比较low一点、折中一点的解决方案。

这个问题还不至于底层让步,现在关键在于如果我们能知道一个bean出现循环依赖了,我们就提前AOP,没有出现循环依赖的,正常走流程,这样不至于所以bean都提前AOP,没有对原先的架构造成破坏,也做了一点妥协,部分bean需要提前AOP,是一个比较折中的方案。

所以加了第三级缓存singletonFactories,作用就是解决AOP问题,在earlySingletonObjects之前加一层缓冲,因为我也不知道现在这个bean是不是循环依赖了,所以不能过早暴露出来。

对应上述例子,

实例化A,放入singletonFactories(不知道A是循环依赖对象),...

...

...

...

实例化C,需要注入A

singletonObjects找A没有

earlySingletonObjects找A没有

singletonFactories找A,找到了

调用singletonFactories的get方法,此时在这里就可以知道A是否循环依赖了,循环依赖了就提前AOP返回代理对象,没有循环依赖就返回原始对象。

remove singletonFactories的A

add earlySingletonObjects A

...

...

...

这样三级缓存的条件下,解决了循环依赖(部分场景)+AOP的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425960.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【FFT】快速傅里叶变换

开个新坑, 快速傅里叶变换在现在世界的各个领域都发挥重要作用。 包括音视频压缩、5G、WIFI、卷积、航空、雷达、核武等等 为什么使用快速傅里叶变换 快速傅里叶变换计算复杂度仅为O(nlogn) 而原傅里叶变换是O(n^2) 什么是快速傅里叶变换 是指对傅里叶变换中的重…

蓝桥杯嵌入式第十一届客观题解析

文章目录 前言一、题目1二、题目2三、题目3四、题目4五、题目5六、题目6七、题目7八、题目8九、题目9十、题目10总结前言 本篇文章将为大家带来蓝桥杯嵌入式省赛第11届客观题的解析。 一、题目1 积分电路的作用是对输入信号进行积分,因此在输入一个矩形波时,输出波形将是输…

租车管理系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设!!! 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址:https://download.csdn.net/download/qq_50954361/87682508 更多系统资源库…

【MySQL】索引优化与查询优化(重点:索引失效的11种情况)

【大家好,我是爱干饭的猿,本文重点介绍MySQL的内连接、外连接、索引失效的11种情况、关联查询优化、子查询优化、排序优化、GROUP BY优化、优化分页查询、覆盖索引、索引条件下推和其它查询优化策略的一些问题。 后续会继续分享MySQL和其他重要知识点总…

Springboot基础学习之(二十一):Swagger基础学习(swagger信息介绍,配置扫描接口和开关,分组和接口注释)

什么是Swagger? Swagger2是一个规范和完整的框架,用于生成、描述、调用和可视化RESTful 风格的Web 服务 使用Swagger你只需要按照它的规范去定义接口及接口相关的信息。再通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口…

Flutter 滚动组件ListView,GridView,Sliver以及滚动监听

前言 身是菩提树 心是明镜台 时时勤拂拭 模式染尘埃 这玩意不难,就是东西多。。。 1 看一下继承关系 class GridView extends BoxScrollView abstract class BoxScrollView extends ScrollView abstract class ScrollView extends StatelessWidget 2 下面是scr…

set和map

set和map关联式容器键值对树状结构关联式容器set介绍使用multiset介绍使用map介绍使用multimap介绍使用底层容器AVL树概念操作节点定义插入旋转红黑树(RBTree)概念节点的设计迭代器的设计结构插入红黑树模拟实现set与map模拟实现map模拟实现set关联式容器…

【Java 数据结构】单向链表和双向链表的实现 (LinkedList)

🎉🎉🎉点进来你就是我的人了 博主主页:🙈🙈🙈戳一戳,欢迎大佬指点!人生格言:当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔🦾&am…

android studio 页面布局(2)

<?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"xmlns:tools"http://schemas.android.com/too…

【数据挖掘与商务智能决策】第九章 随机森林模型

9.1.3 随机森林模型的代码实现 和决策树模型一样&#xff0c;随机森林模型既可以做分类分析&#xff0c;也可以做回归分析。 分别对应的模型为随机森林分类模型&#xff08;RandomForestClassifier&#xff09;及随机森林回归模型&#xff08;RandomForestRegressor&#xff…

Vue.js 2.0 组件

什么是组件&#xff1f; 组件&#xff08;Component&#xff09;是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素&#xff0c;封装可重用的代码。在较高层面上&#xff0c;组件是自定义元素&#xff0c; Vue.js 的编译器为它添加特殊功能。在有些情况下&#xff0c;组件也…

《花雕学AI》19:比较ChatGPT与新Bing在文章润色方面的应用优势与测试案例

引言&#xff1a; 文章润色是指对已经写好的文章进行修改、优化或完善的过程&#xff0c;以提高文章的质量和效果。文章润色涉及到多方面的内容&#xff0c;如语言表达、逻辑结构、文献引用、格式规范等。文章润色对于提升写作水平、提高论文发表率、增加学术影响力等都有重要意…

JavaScript【趣味】做一个网页版2048

文章目录&#x1f31f;前言&#x1f31f;先看效果&#xff08;粉丝特权哈哈&#xff09;&#x1f31f;代码实现&#x1f31f;页面布局 【index.html】&#x1f31f;样式文件【2048.css】&#x1f31f;index.html 里用到的JS文件&#x1f31f;jquery.min.js&#x1f31f;util.js…

300元左右的蓝牙耳机哪个好?300左右音质最好的蓝牙耳机

无线耳机是人们日常生活中必不可少的设备&#xff0c;无论是听音乐化石看电影都能获得身临其境的感觉&#xff0c;由于科技真在发展中&#xff0c;不断地的发生变化&#xff0c;百元价位就可以感受到不错的音色&#xff0c;下面小编整理了几款300左右音质表现不错的蓝牙耳机。 …

Linux 、Android将在汽车舞台上开战

导读在 CES 2017 上&#xff0c;AGL 宣布&#xff0c;Mercedes-Benz 的母公司 Daimler 正式加入。这是第十家汽车制造商加入 AGL&#xff0c;也是第一家德国公司加入 AGL。AGL&#xff08;Automotive Grade Linux&#xff09;&#xff0c;是 Linux 基金会的一个相互协作的开源组…

mallox勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

目录 前言&#xff1a; 一、mallox勒索病毒及xollam勒索病毒的特点 二、mallox勒索病毒及xollam勒索病毒的影响 三、mallox勒索病毒及xollam勒索病毒数据恢复服务 四、mallox勒索病毒及xollam勒索病毒加密数据库恢复案例 五、以下是预防mallox勒索病毒及xollam勒索病毒安全…

解读CANDT测试项-采样点测试

原标题&#xff1a;解读CANDT测试项-采样点测试 一、为什么要进行采样点测试&#xff1f; 本文引用地址&#xff1a;http://www.eepw.com.cn/article/202004/411611.htm 为了保证有效的通信&#xff0c;对于一个只有两个节点的CAN网络&#xff0c;其两边距离不超过最大的传输…

day12 共享内存(内存映射的使用、注意事项、进程间通信、systemV共享内存)

内存映射的基本使用 概念&#xff1a; 功能共享内存可以通过mmap&#xff08;&#xff09;映射普通文件。 是一个磁盘文件与内存中的一个缓冲区相映射&#xff0c;进程可以像访问普通内存一样对文件进行访问&#xff0c;不必在调用read 、write。 mmap&#xff08;&#xf…

ChatGPT 与 MindShow 一分钟搞定一个PPT

前言 PPT制作是商务、教育和各种场合演讲的重要组成部分。然而&#xff0c;很多人会花费大量时间和精力在内容生成和视觉设计方面。为了解决这个问题&#xff0c;我们可以利用两个强大的工具——ChatGPT和MindShow&#xff0c;来提高制作PPT的效率。 一、ChatGPT 与 MindShow…

JUC-01 线程的创建和状态转换

本次我们主要讲三个问题 线程是什么&#xff1f;线程有哪些状态&#xff1f;各状态间的转换了解吗&#xff1f;创建线程的3种方法你都了解吗&#xff1f; 1. 线程是什么&#xff1f;&#xff08;了解即可&#xff09; 进程&#xff1a; 进程是一个具有一定独立功能的程序在一…