https://mp.weixin.qq.com/s/FtbzTMxHgzL0G1R2pSlh-A

通常来说,如果问Spring内部如何解决循环依赖,一定是单默认的单例Bean中,属性互相引用的场景。比如几个Bean之间的互相引用:

甚至自己“循环”依赖自己:

先说明前提:原型(Prototype)的场景是不支持循环依赖的,通常会走到AbstractBeanFactory类中下面的判断,抛出异常。

if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

原因很好理解,创建新的A时,发现要注入原型字段B,又创建新的B发现要注入原型字段A...

这就套娃了, 你猜是先StackOverflow还是OutOfMemory?Spring怕你不好猜,就先抛出了BeanCurrentlyInCreationException

基于构造器的循环依赖,就更不用说了,官方文档都摊牌了,你想让构造器注入支持循环依赖,是不存在的,不如把代码改了。那么默认单例的属性注入场景,Spring是如何支持循环依赖的?

Spring解决循环依赖

首先,Spring内部维护了三个Map,也就是我们通常说的三级缓存。笔者翻阅Spring文档倒是没有找到三级缓存的概念,可能也是本土为了方便理解的词汇。在Spring的DefaultSingletonBeanRegistry类中,你会赫然发现类上方挂着这三个Map:

  • singletonObjects 它是我们最熟悉的朋友,俗称“单例池”“容器”,缓存创建完成单例Bean的地方。
  • singletonFactories 映射创建Bean的原始工厂
  • earlySingletonObjects 映射Bean的早期引用,也就是说在这个Map里的Bean不是完整的,甚至还不能称之为“Bean”,只是一个Instance.

后两个Map其实是“垫脚石”级别的,只是创建Bean的时候,用来借助了一下,创建完成就清掉了。所以笔者前文对“三级缓存”这个词有些迷惑,可能是因为注释都是以Cache of开头吧。为什么成为后两个Map为垫脚石,假设最终放在singletonObjects的Bean是你想要的一杯“凉白开”。那么Spring准备了两个杯子,即singletonFactories和earlySingletonObjects来回“倒腾”几番,把热水晾成“凉白开”放到singletonObjects中。

【Spring】 Spring如何解决循环依赖的问题?的更多相关文章

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

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

  2. spring: 我是如何解决循环依赖的?

    1.由同事抛的一个问题开始 最近项目组的一个同事遇到了一个问题,问我的意见,一下子引起的我的兴趣,因为这个问题我也是第一次遇到.平时自认为对spring循环依赖问题还是比较了解的,直到遇到这个和后面的 ...

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

    前言 相信很多小伙伴在工作中都会遇到循环依赖,不过大多数它是这样显示的: 还会提示这么一句: Requested bean is currently in creation: Is there an ...

  4. 听说你还不知道Spring是如何解决循环依赖问题的?

    Spring如何解决的循环依赖,是近两年流行起来的一道Java面试题. 其实笔者本人对这类框架源码题还是持一定的怀疑态度的. 如果笔者作为面试官,可能会问一些诸如"如果注入的属性为null, ...

  5. Spring三级缓存解决循环依赖

    前提知识 1.解决循环依赖的核心依据:实例化和初始化步骤是分开执行的 2.实现方式:三级缓存 3.lambda表达式的延迟执行特性 spring源码执行逻辑 核心方法refresh(), popula ...

  6. 浅谈Spring解决循环依赖的三种方式

    引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错.下面说一下Spring是如果解决循环依赖的. 第一种: ...

  7. Spring 如何解决循环依赖问题?

    在关于Spring的面试中,我们经常会被问到一个问题,就是Spring是如何解决循环依赖的问题的. 这个问题算是关于Spring的一个高频面试题,因为如果不刻意研读,相信即使读过源码,面试者也不一定能 ...

  8. Spring ioc(4)---如何解决循环依赖

    前面说到对象的创建,那么在创建的过程中Spring是怎么又是如何解决循环依赖的呢.前面提到有个三级缓存.就是利用这个来解决循环依赖.打个比方说实例化A的时候,先将A创建(早期对象)放入一个池子中.这个 ...

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

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

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

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

随机推荐

  1. 防数据泄露_MySQL库和数据安全

    目录 攻击场景 外部入侵 内部盗取 防御体系建设 参考 在企业安全建设中有一个方向是防数据泄露,其中一块工作就是保障数据库安全,毕竟这里是数据的源头.当然数据库也分不同的种类,不同类型的数据库的防护手 ...

  2. linux 几种传输文件的方式

    SimpleHTTPServer + wget 如果线上可以直连线下的话,在线上使用wget访问线下的文件服务器: web的方法,比较灵活,使用完要尽快关闭这个服务: cd temp temp$ py ...

  3. 解决 DatePickerDialog 在 Android7.0 API24 上使用 AlertDialog.THEME_TRADITIONAL、AlertDialog.THEME_HOLO_DARK、AlertDialog.THEME_HOLO_LIGHT等样式时无法显示为 Spinner 样式的问题

    DatePickerDemoForAndroid24 解决 DatePickerDialog 在 Android7.0 API24 上使用AlertDialog.THEME_TRADITIONAL.A ...

  4. 小程序基于Token登录 示意图

  5. 基于es实现一个简单的搜索引擎

    一.什么是es Elasticsearch是一个基于ApacheLucene(TM)的开源搜索引擎.无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进.性能最好的.功能最全的搜索引擎库.但 ...

  6. git配置,以及简单的命令

    在 window 平台需要安装对应的客户端 git 配置全局用户名git config --global user.name "xxx"配置全局邮箱git config --glo ...

  7. Intellij IDEA maven设置tomcat

    1 pom.xml配置插件 <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId&g ...

  8. pyspider的环境安装

    第一:确认自己的Python版本3.6.x(因该版本与pyspider较为适应,其他版本易出错) 如果不是3.6版本的,且想将版本替换成3.6版本的有以下处理方法: 1.再装一个3.6版本python ...

  9. 绿色物流-智慧仓储监控管理 3D 可视化系统

    前言 随着电子商务产业的迅速发展,快递爆仓已成为了困扰仓储物流的一大难题.大量的碎片化订单,传统仓储管理和运作方式已无法满足,加速仓储物流管理的智能化.自动化升级创新,延伸而出的智慧物流概念成为物流行 ...

  10. Java中的Set集合

    Set接口简介 Set接口和List接口一样,同样继承自Collection接口,它与Collection接口中的方法基本一致,并没有对Collection接口进行功能上的扩充,它是比Collecti ...