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

相关推荐
10km13 分钟前
java:Apache Commons Configuration2占位符解析异常的正确解法:${prefix:name:-default}
java·apache·configuration2·变量插值·interpolation
customer0813 分钟前
【开源免费】基于SpringBoot+Vue.JS个人博客系统(JAVA毕业设计)
java·vue.js·spring boot·后端·开源
qq_4592384917 分钟前
SpringBoot整合Redis和Redision锁
spring boot·redis·后端
灰色人生qwer21 分钟前
SpringBoot 项目配置日志输出
java·spring boot·后端
2301_7930698231 分钟前
Spring Boot +SQL项目优化策略,GraphQL和SQL 区别,Spring JDBC 等原理辨析(万字长文+代码)
java·数据库·spring boot·sql·jdbc·orm
阿华的代码王国37 分钟前
【从0做项目】Java搜索引擎(6)& 正则表达式鲨疯了&优化正文解析
java·后端·搜索引擎·正则表达式·java项目·从0到1做项目
服务端相声演员37 分钟前
Oracle JDK、Open JDK zulu下载地址
java·开发语言
是姜姜啊!38 分钟前
java连接redis
java·redis
hhw19911240 分钟前
spring boot知识点5
java·数据库·spring boot
EQUINOX142 分钟前
lab4 CSAPP:Cachelab
java·后端·spring