Spring 解决单例 bean 的循环依赖主要依赖于容器的三级缓存机制,以及 bean 的提前暴露。这里是它如何工作的:

  1. 三级缓存:

    • 一级缓存(singletonObjects):存储已经经过完整生命周期处理的单例 bean,包括初始化和依赖注入等。
    • 二级缓存(earlySingletonObjects):存储早期的单例对象的引用,这些对象已经被实例化但是还没有完全初始化(主要是没有进行依赖注入)。
    • 三级缓存(singletonFactories):存储用于生成早期单例对象引用的工厂对象。
  2. 提前暴露:

    • 当 Spring 容器创建一个单例 bean 的时候,首先会实例化这个 bean,并将实例化后的 bean 放入三级缓存中。
    • 接着,Spring 容器会尝试进行依赖注入。如果发现有依赖其他 bean 的情况,它会尝试去获取这些依赖的 bean。
    • 如果这个时候发生了循环依赖,即当前 bean A 正在创建过程中(尚未完成依赖注入),并且需要依赖另一个 bean B,而 bean B 同时也在创建过程中需要依赖 bean A,这时候 Spring 容器就会从三级缓存中获取到 bean A 的早期引用解决循环依赖。
  3. 循环依赖的处理流程:

    • 当容器创建 bean A 的时候,会将其包装好的 ObjectFactory 放入三级缓存中。
    • 如果 bean A 依赖 bean B,容器会去创建 bean B,在创建 bean B 的过程中,如果 bean B 又依赖于 bean A,此时会尝试从缓存中获取 bean A。
    • 首先尝试从一级缓存中获取,如果没有,则从二级缓存中获取,如果还没有,则从三级缓存中通过 ObjectFactory 获取 bean A 的早期引用。
    • 这个早期引用是允许注入到其他 bean 中的,但此时 bean A 可能还没有完成完整的生命周期处理。
    • 一旦 bean A 和 bean B 都创建完毕,它们就会被添加到一级缓存中,并从二级和三级缓存中移除。

通过这种方式,Spring 能够处理大多数的循环依赖情况。需要注意的是,Spring 只能自动解决单例作用域的 bean 的循环依赖问题,对于原型作用域的 bean,Spring 容器不会尝试解决循环依赖,这可能会导致无限循环或者其他不可预期的问题。

spring--是如何解决单例模式下循环依赖问题的的更多相关文章

  1. Spring IOC 容器源码分析 - 循环依赖的解决办法

    1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...

  2. 深谈Spring如何解决Bean的循环依赖

    1. 什么是循环依赖 Java循环依赖指的是两个或多个类之间的相互依赖,形成了一个循环的依赖关系,这会导致程序编译失败或运行时出现异常.下面小岳就带大家来详细分析下Java循环依赖. 简单来讲就是:假 ...

  3. spring如何解决单例循环依赖问题?

    更多文章点击--spring源码分析系列 1.spring循环依赖场景2.循环依赖解决方式: 三级缓存 1.spring循环引用场景 循环依赖的产生可能有很多种情况,例如: A的构造方法中依赖了B的实 ...

  4. 解决spring boot 2.6.4版本循环依赖问题

    引用spring boot 2.6.4 版本 报循环依赖错误 *************************** APPLICATION FAILED TO START ************* ...

  5. Spring是如何解决循环依赖的

    前言 在面试的时候这两年有一个非常高频的关于spring的问题,那就是spring是如何解决循环依赖的.这个问题听着就是轻描淡写的一句话,其实考察的内容还是非常多的,主要还是考察的应聘者有没有研究过s ...

  6. Spring解决循环依赖,你真的懂了吗?

    导读 前几天发表的文章SpringBoot多数据源动态切换和SpringBoot整合多数据源的巨坑中,提到了一个坑就是动态数据源添加@Primary接口就会造成循环依赖异常,如下图: 这个就是典型的构 ...

  7. Spring如何解决循环依赖,你真的懂了?

    导读 前几天发表的文章SpringBoot多数据源动态切换和SpringBoot整合多数据源的巨坑中,提到了一个坑就是动态数据源添加@Primary接口就会造成循环依赖异常,如下图: 这个就是典型的构 ...

  8. Spring框架系列(8) - Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等)

    上文,我们看了IOC设计要点和设计结构:以及Spring如何实现将资源配置(以xml配置为例)通过加载,解析,生成BeanDefination并注册到IoC容器中的:容器中存放的是Bean的定义即Be ...

  9. 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖

    本次博客的目标 1. 手写spring循环依赖的整个过程 2. spring怎么解决循环依赖 3. 为什么要二级缓存和三级缓存 4. spring有没有解决构造函数的循环依赖 5. spring有没有 ...

  10. Spring里bean之间的循环依赖解决与源码解读

    通过前几节的分析,已经成功将bean实例化,但是大家一定要将bean的实例化和完成bean的创建区分开,bean的实例化仅仅是获得了bean的实例,该bean仍在继续创建之中,之后在该bean实例的基 ...

随机推荐

  1. lca 学习笔记

    定义 最近公共祖先简称 \(LCA\) 两个节点的最近公共祖先,就是这两个点的公共祖先里,离根最远的的那个 为了方便,我们记某点集 \(S={v1,v2,...,vn}\) 的最近公共祖先为 \(LC ...

  2. 华企盾DSC忘记了数据库解锁密码

    解决方法:登录数据库控制台,找到DSE所使用数据库默认名字"DSEDB",打开表"FileEncryptKey_TABLE",如下图所示: ​ 第一行,自动生成 ...

  3. python 图片相关

    python 图片相关 本篇介绍两种方式来打开图片. 1: 使用matplotlib #!/usr/bin/python3 # -*- coding: UTF-8 -*- ""&q ...

  4. 盘点前端的那些Ajax请求:从ES5到React

    说起前端开发,Ajax请求是绕不开的技术点.然而,程序语言更新换代越来越快,Ajax请求的方式也是各有不同. 在使用ES5开发的时候,我们还在使用最原始的XMLHttpRequest对象: // cr ...

  5. markdown中插入视频前台渲染出来导致<video>等标签被转义成字符

    markdown中插入视频前台渲染出来导致<video>等标签被转义成字符解决办法: 如图: 在markdown里面插入视频,可以按照下面写法,哈哈,虽然很捞,但是还是可以满足的. < ...

  6. 【笔记】负载均衡Robbin之不同服务使用不同的策略

    裂开裂开,搞这么久忘记导入依赖 妈卖批 又不报错 还能让我玩 我以为全部导入了. 话不多说,开始演示. 介绍 给不同的服务 配置 不同的 负载均衡策略 这里使用 用户模块 进行访问其它两个模块的con ...

  7. 某物流客户Elasticsearch集群性能优化案例

    客户背景 客户使用ES来进行数据存储.快速查询业务订单记录,但是经常会出现业务高峰期ES集群的cpu负载.内存使用均较高,查询延迟大,导致前端业务访问出现大量超时的情况,极大影响其客户使用体验. 部分 ...

  8. springboot-jpa获取session

    springboot获取hibernate的session进行更精细的SQL操作,默认的jpa并不能满足一些复杂需求(可能是我把需求设计复杂了) 通过查看JpaRepository的底层实现,发现是通 ...

  9. 记录:websoket切换页面后重复执行问题

    问题描述 因为项目需求,实时播放执行信息.而项目的websoket只在这个页面,会有切换情况.从websoket连接得到执行列表数据.断开重连后会传递新连接数据+旧连接数据.也就是说,如果第一次进入页 ...

  10. 最终,我决定将代码迁出x86架构!

    如今,我们几乎所有软件都建立在 x86 架构之上 ,在互联网漫长的演进过程中,各大公司拼尽全力在迭代上层架构.优化整体性能,开发者们该用的.能用的招儿想必都用上了,接下来呢?如果底层架构不出现大的革新 ...