Spring-循环依赖是如何解决的

1、bean被创建保存到spring容器的过程

1、实例化 -> 获取对象;

2、填充属性;这里可能需要依赖其它的bean。

3、AOP代理对象替换;

4、加入单例池;

问题:

循环依赖怎么处理

ServiceA 中有属性ServiceB b;

ServiceB中有属性ServerA a;

如何打破循环?

在第1步中,aService实例化后存入到map中。在2.2步中,如果单例池中没有,再去查前面的map。这样就打破了无限循环逻辑。

如果循环依赖中的bean是需要做AOP替换的代理对象,问题又该如何解决?

需要提前进行AOP创建代理对象-早期对象。

2、spring容器启动过程中用到的三个map

1、单例池 singletoneObjects,存储完整的bean实例;

2、早期的单例池 earlySingletonObjects,用于解决AOP代理对象的问题;确保创建过程中的不完整的对象也是单例的。

3、singletonFactories,value是一个Function。

如果没有三级缓存singletonFactories,那么在创建AOP代理对象时就无法获取到原目标target普通对象。如果可以获取到到target对象,那么循环就会被打破,循环问题就解决了。

所以singletonFactories中的value其实是一个获取早期对象的函数,里面可能返回普通对象也可能返回AOP对象,但都是没有执行完完整实例化过程的对象(早期对象),这里设计比较巧妙。

3、为什么不先实例化所有的bean,再进行属性依赖注入?

Spring 容器在启动时不会立即实例化所有的 bean,因为这样做可能会创建许多不会被用到的 bean 实例,从而浪费内存和初始化时间。相反,Spring 容器按需创建 bean,即当应用程序请求一个 bean 时,容器才会创建它,并且如果该 bean 依赖其他 bean,则先实例化依赖的 bean。

这种懒加载(Lazy Loading)的策略使得容器更加高效,因为它只实例化必需的组件,从而节省资源。

也会存在构造注入的场景,所以这时也是先需要其它bean实例的。

3、哪些场景下Spring还是会报循环依赖的错误?

1、@Async + 循环依赖 。

解决:-> 添加@Lazy

2、循环依赖&唯一构造注入

根本无法实例化!因为构造函数中的逻辑循环了!

解决:改成属性注入而非构造!

学习资料参考:

3、什么是二级缓存,它的作用是什么?_哔哩哔哩_bilibili

相关推荐
侠客行03175 小时前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪5 小时前
深入浅出LangChain4J
java·langchain·llm
Victor3565 小时前
https://editor.csdn.net/md/?articleId=139321571&spm=1011.2415.3001.9698
后端
Victor3565 小时前
Hibernate(89)如何在压力测试中使用Hibernate?
后端
灰子学技术7 小时前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
老毛肚7 小时前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎7 小时前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
Yvonne爱编码7 小时前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚7 小时前
JAVA进阶之路——无奖问答挑战1
java·开发语言
你这个代码我看不懂7 小时前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言