Spring是如何解决循环依赖的

简介

所谓循环依赖指的是:BeanA对象的创建依赖于BeanB,BeanB对象的创建也依赖于BeanA,这就造成了死循环,如果不做处理的话势必会造成栈溢出。Spring通过提前曝光机制,利用三级缓存解决循环依赖问题。

变量 描述
singletonObjects 一级缓存,key为Bean名称,value为Bean实例。这里的Bean实例指的是已经完全创建好的,即已经经历实例化->属性填充->初始化以及各种后置处理过程的Bean,可直接使用。
earlySingletonObjects 二级缓存,key为Bean名称,value为Bean实例。这里的Bean实例指的是仅完成实例化的Bean,还未进行属性填充等后续操作。用于提前曝光,供别的Bean引用,解决循环依赖。
singletonFactories 三级缓存,key为Bean名称,value为Bean工厂。在Bean实例化后,属性填充之前,如果允许提前曝光,Spring会把该Bean转换成Bean工厂并加入到三级缓存。在需要引用提前曝光对象时再通过工厂对象的getObject()方法获取。

加入三级缓存解决循环依赖

假设容器先创建BeanA,属性填充时,发现BeanA依赖BeanB,然后Spring开始创建BeanB。创建BeanB时候又发现其依赖BeanA,这时三级缓存中已经存在BeanA的工厂对象了,所以直接通过该工厂对象获取BeanA的早期实例,因此不会抛出循环依赖异常。

总结

虽然spring已经加入三级缓存解决绝大部分循环依赖的问题,但是我们在编码过程中仍然不建议出现循环依赖,因为这会增加代码的复杂度,不利于排查问题。

相关推荐
好奇的菜鸟3 分钟前
Go语言中的引用类型:指针与传递机制
开发语言·后端·golang
所待.3837 分钟前
JavaEE之线程初阶(上)
java·java-ee
Winston Wood10 分钟前
Java线程池详解
java·线程池·多线程·性能
Alive~o.012 分钟前
Go语言进阶&依赖管理
开发语言·后端·golang
手握风云-15 分钟前
数据结构(Java版)第二期:包装类和泛型
java·开发语言·数据结构
许苑向上18 分钟前
Dubbo集成SpringBoot实现远程服务调用
spring boot·后端·dubbo
喵叔哟35 分钟前
重构代码中引入外部方法和引入本地扩展的区别
java·开发语言·重构
尘浮生41 分钟前
Java项目实战II基于微信小程序的电影院买票选座系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
郑祎亦1 小时前
Spring Boot 项目 myblog 整理
spring boot·后端·java-ee·maven·mybatis
不是二师兄的八戒1 小时前
本地 PHP 和 Java 开发环境 Docker 化与配置开机自启
java·docker·php