深入了解Spring循环依赖本质

从DDH到FastANI:原核生物分类黄金标准的进化史与技术对比 本文系统梳理了原核生物分类标准从DDH到FastANI的四次技术革命,详细解析了95%相似度阈值的科学依据及应用场景。通过对比DDH、16S rRNA、ANI和FastANI的技术特点与性能指标,为微生物研究者提供基因组分类的实战指南,并展望第三代测序时代的分类新挑战。 阅读详情

说明:

  1. 本文基于Spring-Framework 5.1.x版本讲解

  2. 建议读者对创建对象部分源码有一定了解

概述

这篇讲讲Spring循环依赖的问题,网上讲循环依赖的帖子太多太多了,相信很多人也多多少少了解一点,那我还是把这个问题自己梳理一遍,主要是基于以下出发点:

1. Spring到底如何解决的循环依赖问题,有没有’黑科技‘;

2. 有时项目会因为循环依赖问题导致启动失败,由于不了解其机制,排查耗费时间

3. 网上众说风云,没有形成自己的思考

还有其他文章说Spring使用三级缓存是为了解决循环依赖问题,为了解决代理下的循环依赖问题? 那废话不多说,直接开始吧

循环依赖简介

循环依赖的含义: BeanA依赖BeanB,BeanB又依赖BeanA , 如下图

这就是循环依赖, 我们来分析下会有什么问题?

1. 实例化BeanA

2. BeanA在属性注入阶段从容器里面找BeanB

3. 如果BeanB已经在容器里面创建好,那万事大吉,没循环依赖的问题

4. 如果BeanB还没有在容器里面创建好,这时候Spring会创建BeanB

5. 创建BeanB的时候又发现依赖BeanA,但此时BeanA也没有创建完,在没有开启循环依赖开关的情况下就会报错:Requested bean is currently in creation: Is there an unresolvable circular reference?

从软件代码分层结构来讲,如果分层合理,这种情况一般可以避免掉,但是避免不了同一个层次中的Bean互相引用,好那既然循环依赖肯定会出现,我们自己先来思考下,如果是我们自己写一个IOC容器,这个问题如何解决?

如何解决循环依赖?

从上面的4步可以看出来,问题所在就是BeanB在创建过程中,无法找到正在创建中的BeanA,那我们是不是可以找一个地方把正在创建的BeanA(为了行文方便,把Bean正在创建中的状态称为半状态)先给保存起来,等BeanB用到的时候赋值给它不就行了,这时候步骤如下:

1. 实例化BeanA

2. BeanA在属性注入之前先把自己放到一个Map里面(此时BeanA为半状态)

3. BeanA在属性注入阶段从容器里面找BeanB

4. 如果BeanB还没有在容器里面创建好,这时候Spring会创建BeanB

5. 创建BeanB的时候又发现依赖BeanA,由于BeanA已经在Map里面了(虽然是半状态,但不影响最终使用,反正现在又不暴露给用户使用) ,所以注入成功,BeanB创建完成

6. 由于BeanB已创建完成,意味着BeanA注入BeanB成功,此时从Map中移除BeanA的半状态

7. 容器初始化完成

到这里有什么大的问题没有? 其实是没有的,Bean确实会创建成功 , 容器可以正常启动完成。 那我们在来看下启用动态代理情况下,使用一个Map(一级缓存)会不会有问题? 为了说明简单,我们只生成BeanA的代理对象BeanA_Proxy,BeanB无需创建:

1. 实例化BeanA,并生成BeanA的代理对象BeanA_Proxy ,此时上下文中有BeanA、BeanA_Proxy两个对象

2. BeanA在属性注入之前先把代理对象BeanA_Proxy放到Map里面

3. BeanA在属性注入阶段从容器里面找BeanB

4. 如果BeanB还没有在容器里面创建好,这时候Spring会创建BeanB

5. 创建BeanB的时候又发现依赖BeanA,由于BeanA的代理对象BeanA_Proxy已经在Map里面了,所以把BeanA_Proxy注入BeanB,此时BeanB创建完成

6. 由于BeanB已创建完成,意味着BeanA注入BeanB成功,此时从Map中移除BeanA_Proxy

7. 容器把BeanA_Proxy暴露给用户使用,并初始化完成

从上面可以看出,即使使用代理的情况下,使用一个Map(一级缓存)来解决循环依赖问题也是可以的。

为什么是三级缓存?

从上面可以看出,把半状态的Bean或者代理对象无脑的放入一级缓存之后,确实可以解决循环依赖的问题,那为什么Spring要使用三级缓存来解决这个问题呢? 让我们来回忆下Bean的整个生命周期: 1. 实例化Bean 2. 属性注入 3. 初始化Bean 。 这是创建一个Bean必经的几个步骤,而我们上面是为了解决循环依赖问题而强行加了一个往一级缓存里面放对象的步骤,而对于不存在循环依赖的对象,这一步无疑是多余的;还有另外一个问题: 把半状态的Bean和创建完成的Bean对象放入同一个缓存里面也不太好管理,违背单一职能原则

所以这里我们要解决2个问题:

1. 解决循环依赖的代码(也就说生成半状态对象的过程)不能放到创建Bean的主流程中;

2. 半状态的对象需要与创建完成的对象所在的容器隔离开。

为了解决问题一我们可以考虑在检测到有循环依赖的时候才把半状态对象暴露给BeanB使用,就是说说BeanB发现BeanA正在创建的时候,在把半状态BeanA赋值给BeanB。 但是问题又来了:这个半对象BeanA哪来的? 谁创建出来的? 这无疑变成了蛋和鸡的问题, 所以我们还是要在刚开始创建BeanA的时候以最小的代价(这里指执行时间最短) 把半对象给保存起来,BeanB检测到循环依赖的时候,在把BeanA给取出来。那Spring其实就是使用另一个Map保存匿名函数的方式来解决这个问题的, 因为你要考虑直接暴露BeanA的代价(比如说暴露给BeanB是一个代理对象,那要考虑创建BeanA代理对象的执行成本)。 这里我们简单贴下Spring的源码:

/** * 实际生成Bean的核心方法 */protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { 
// 省略上下文中其他不重要的代码 
// 这里注册一个匿名函数,把匿名函数放到一个临时缓存里面(其实就是所谓的三级缓存) addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));} 
/** * 作用: 获取提前要暴露给其他Bean的引用 * 这个方法只有在Spring检测到有循环引用的情况下才会调进来 */protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; 
// 获取要提前暴露的对象,这里有可能产生代理对象以及其他非入参Bean的对象 exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } return exposedObject;}

好,看到这里其实我们已经顺便把上述第二个问题也一起解决掉了,因为保存匿名函数的Map和最终保存对象实例的Map不是同一个,而且保存匿名函数的Map在解决完循环依赖问题之后会清空掉,这样我们就可以以延迟加载的方式解决掉循环依赖的问题。 那在BeanA会产生代理的情况下会不会有问题??? 请你自己思考下

但这里还有一个问题,考虑下面一种场景:

​BeanA与BeanB、BeanC的关系是互相引用, 套用我们上面的理论, 在创建BeanA的主流程中我们只是插入了一个获取半状态对象的匿名函数,而不是要暴露给外部的最终对象,当BeanC也需要注入BeanA的时候,还是要执行一次匿名函数来获取最终暴露的对象,这里有两个问题:

1. 匿名函数重复执行,其实是没有必要的。

2. 更为严重的是,有可能每次调用函数返回的是不同的对象,这样会导致注入给BeanB和BeanC的对象不一致,这就是大问题了。 (那有人会问如果保证获取最终暴露对象的接口SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference中返回同一个对象不就行了? 站在解决问题的角度确实是这样的,但是站在容器的角度来讲就不一样了,接口只是一个拓展点,他的执行逻辑是不可控的,所以还是要在容器级别来解决这个问题)

为了解决以上两个问题,Spring采用了第三个缓存,把已经暴露出去的对象给缓存起来,这样问题就完美解决以上两个问题。

getEarlyBeanReference

在上面我们已经解释了为什么要用三级缓存来解决循环依赖的问题,我们在简单说下SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference接口,其实这个接口没有什么高深的地方,只是为了获取循环依赖下需要提前暴露给其他Bean的对象,这里要注意一下:仅仅在检测到有循环依赖的情况下才会调进来,我们看下接口定义

/** * Extension of the {@link InstantiationAwareBeanPostProcessor} interface, * adding a callback for predicting the eventual type of a processed bean. * * <p><b>NOTE:</b> This interface is a special purpose interface, mainly for * internal use within the framework. In general, application-provided * post-processors should simply implement the plain {@link BeanPostProcessor} * interface or derive from the {@link InstantiationAwareBeanPostProcessorAdapter} * class. New methods might be added to this interface even in point releases. * * @author Juergen Hoeller * @since 2.0.3 * @see InstantiationAwareBeanPostProcessorAdapter */public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor { default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { return bean; }}

从类注释中”This interface is a special purpose interface, mainly for internal use within the framework“可以看到,这个接口仅仅是Spring内部为了解决某些问题提供的接口,并不希望暴露给上层用户使用,所以我们在实际工作中一般用不到的

但是我们要特别注意一个坑: 我们知道在Bean后置处理接口BeanPostProcessor中也有可能返回代理对象,如果这里返回的对象和循环依赖暴露出去的对象不一致的话就会报以下错误:

Error creating bean with name 'serviceA': Bean with name 'serviceA' has been injected into other beans [serviceB] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'serviceA': Bean with name 'serviceA' has been injected into other beans [serviceB] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example. at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:622) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:514) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:321) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:319) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:866) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) at test.circle_ref.CircleRefTests.run(CircleRefTests.java:13)

从逻辑上来讲报错也是合理的,因为既然提前暴露出去的Bean,像是一种承诺,后续就不能修改了,修改意味着Spring容器中Bean的’状态‘是不一致的。 所以在有循环依赖的情况下,一定要保证getEarlyBeanReference和BeanPostProcessor 返回的Bean是同一个。

小结

本篇文章介绍了Spring为什么用三级缓存才解决循环依赖问题,并且介绍了SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference接口的含义以及在实际情况中可能遇到的坑,那我们总结下Spring的三级缓存的作用:

一级缓存: 保存已经创建完的Bean对象,我们常用的BeanFactory#getBean方法就是从这里获取;

二级缓存: 缓存在循环依赖中暴露给其他Bean的半状态对象,防止注入对象不一致的问题;

三级缓存: 缓存获取提前暴露的Bean的匿名函数 ,为的是以最小的代价减少对Spring创建对象主干流程的影响

关于循环依赖的问题就介绍到这,不得不说Spring考虑问题真是的非常全面,设计相当合理。如有疑问,欢迎交流

[XJTUSE DATABASE]——第三章 关系数据库标准语言SQL 新年了,来个大的,写了好几天,将近9000字,希望对大家有所帮助 阅读详情

相关推荐

Silvaco Atlas入门指南——从零开始掌握半导体器件仿真

本文为Silvaco Atlas半导体器件仿真软件的入门指南,详细介绍了从零开始掌握该工具的核心流程。内容涵盖Atlas的基本概念、仿真流程、核心文件(输入、结构、输出文件)、交互式与批处理两种操作模式,并逐步演示了如何从定义网格、划分区域、设置电极到进行掺杂、选择物理模型并求解,最终获取和分析器件特性的完整步骤。旨在帮助微电子相关专业人员和工程师快速上手这一强大的“数字实验室”,提升半导体器件设计与研发效率。

weixin_29306317的博客 404

java的销毁方法_销毁Spring Bean的三种方法

@PreDestroy Java标准注解实现DisposableBean的Destroy()方法自定义销毁方法XML 配置:Java注解 @Bean(destroy="destroy")Java API AbstractBeanDefinition#setDestroyMethodName(String)DemoApplication.javapackage com.rumenz;public c...

weixin_35160622的博客 491

防雷防浪涌电路设计

通信线路或者电源线路通常会铺设到户外,一旦线路铺到户外后,就需要考虑防雷的问题了,那么怎么设计保护电路,能够防止雷电等浪涌对电路的破坏呢?

manhuami2007的博客 1万+

销毁Spring Bean的三种方法

@PreDestroy Java标准注解 实现DisposableBean的Destroy()方法 自定义销毁方法 XML 配置:<bean destroy=“destroy” … /> Java注解 @Bean(destroy=“destroy”) Java API AbstractBeanDefinition#setDestroyMethodName(String) DemoApplication.java package com.rumenz; public class Demo.

Linux,Java,SpringBoot,Python,Lua略知一点 1422

图像去噪实战:Noise2Noise与Noise2Void在医学影像中的应用(附代码)

本文深入探讨了Noise2Noise与Noise2Void在医学影像去噪中的革命性应用,通过自监督学习技术有效解决临床数据配对难题。文章提供详细的代码实现和临床部署方案,展示如何提升低剂量CT、MRI等影像的诊断质量,特别适用于辐射敏感场景和急诊快速处理。

weixin_29092579的博客 243

音频测试专题

麦克风与扬声器单体测试指标及整机性能测试概述 麦克风测试指标包括频率响应、灵敏度、指向性等10项关键参数,用于评估声音捕捉和信号转换性能。扬声器测试包含频率响应、灵敏度等12项指标,涉及声学特性和物理参数。整机性能测试覆盖安静、嘈杂和正常三种环境,重点检测麦克风底噪、清晰度、扬声器音量及通话质量等12项功能指标。两类单体测试与整机测试共同构成完整的音频设备质量评估体系,确保产品在不同场景下的性能表现。

weixin_52640906的博客 1319

java bean注销_spring boot之 Bean的初始化和销毁(4)

原文:https://blog.youkuaiyun.com/z3133464733/article/details/79189699------------------------------------------------------------------------------------------------------------------------------------------S...

weixin_35749786的博客 325

三维重建/SLAM笔记_最佳学习路线/攻略

本文目的 学习三维重建,需要不少知识,而知识之间又存在不同的依赖关系,为了后来人能少走弯路,也为了对自己的知识框架系统总结,特记录自己的学习路线。 学习心得 关于读书,了解基础知识是一方面,产生疑问也是一方面,为以后知道学习什么留下印象; 一回生,二回熟,看不懂时,大多是因为先验知识不够,没关系,多查多想,总会搞懂的。 学习路线 1.计算机图形学基础(OpenGL基础版)(徐文鹏 清...

惊鸿一博 3294

java实践10浅谈如何理解Spring核心功能IOC和AOP

java实践10浅谈如何理解Spring IOC和AOP 反射 动态代理 SPI

m252131895的博客 337

工业质检升级!C#上位机集成YOLOv8.3.138+Blob分析:尺寸测量+缺陷检测一步到位

工业场景的技术选型,从来不是“选最先进的”,而是“选最适配的”。这个项目的成功,不在于采用了多前沿的技术,而在于找对了“贴合场景的技术组合”和“落地导向的实施思路”。C#上位机的稳定性保障了系统长期运行,YOLOv8.3.138的精度解决了缺陷检测痛点,Blob分析的抗干扰能力确保了尺寸测量准确,三者结合实现了“1+1+1>3”的效果。先摸透场景,再选技术:不要盲目追求最新模型,先深入了解车间环境、生产节奏、精度要求,选择兼容性强、稳定性高的技术方案;数据质量决定模型性能。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 611

搭建自己的MQTT服务器,实现设备上云(Ubuntu+EMQX)

这篇文章教大家在ECS云服务器上部署EMQX,搭建自己私有的MQTT服务器,配置EMQX实现设备上云,设备数据转发,存储;服务器我采用的华为云的ECS服务器,系统选择Ubuntu系统。

2万+

spring手动注册bean,移除bean,获取bean

注意applicationContext.xml文件的路径配置,按自己项目spring配置文件的路径做相应的调整import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import or

我要上天 2万+

YOLOv5源码逐行超详细注释与解读(5)——配置文件yolov5s.yaml

全网最详细的YOLOv5源码解读之配置文件yaml。逐行注释,逐句讲解,一文带你了解yaml。小白必看!

路人贾的博客 1万+

【Spring源码三千问】@Lazy原理分析——它为什么可以解决特殊的循环依赖问题?

@Lazy原理分析——它为什么可以解决特殊的循环依赖问题前言版本约定正文小结彩蛋: 系列博文: 【老王读Spring IoC-0】Spring IoC 引入 【老王读Spring IoC-1】IoC 之控制反转引入 【老王读Spring IoC-2】IoC 之 BeanDefinition 扫描注册 【老王读Spring IoC-3】Spring bean 的创建过程 【老王读Spring IoC-4】IoC 之依赖注入原理 【老王读Spring IoC-5】Spring IoC 小结——控制反转、依赖注入

老王的专栏 5018

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Spring如何解决循环依赖

烂大街的Spring循环依赖该如何回答? 什么是循环依赖? 从字面上来理解就是A依赖B的同时B也依赖了A,就像上面这样,或者C依赖与自己本身。体现到代码层次就是这个样子 @Component public class A { // A中注入了B @Autowired private B b; } --- @Component public class B { // B中注入了A @Autowired private A a; } --- // 自己依赖自己 @Component public c

意田天的博客 2万+

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

【面试宝典】深入了解Spring的循环依赖解决策略

在Spring框架中,循环依赖问题指的是在依赖注入时,由于Bean之间相互引用而导致的初始化问题。这种情况下,Spring容器在创建Bean的过程中,发现Bean A依赖于Bean B,而Bean B又依赖于Bean A,形成了循环依赖关系。在Spring框架中,三级缓存是用来解决循环依赖问题的一种机制。它由Spring容器中的三个缓存组成,用于临时存储正在创建的Bean实例。

Venus's Blog 9161

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【Spring】Spring的循环依赖以及解决方案

​ Spring循环依赖指的是两个或多个Bean之间相互依赖,形成一个环状依赖的情况。通俗的说,就是A依赖B,B依赖C,C依赖A,这样就形成了一个循环依赖的环。​ Spring循环依赖通常会导致Bean无法正确地被实例化,从而导致应用程序无法正常启动或者出现异常。因此,Spring循环依赖是一种需要尽量避免的情况。

长夜烛火的博客 7996

spring 如何解决循环依赖

spring 如何解决循环依赖

快乐的小三菊的博客 3940

【Spring】Spring的循环依赖及解决方案

在Spring框架中,循环依赖是一个非常常见的问题。当两个或多个bean之间相互依赖时,就会产生循环依赖。这种情况可能会导致程序无限循环,从而导致性能问题和程序崩溃。Spring框架通过检测循环依赖并采取相应措施来解决这个问题。例如,使用懒加载的方式来避免循环依赖。但是,有时候我们的代码中可能会有一些错误,导致循环依赖的产生。在这篇博客中,我们将深入探讨Spring循环依赖的问题。我们将讨论如何产生循环依赖,以及如何避免和解决循环依赖。我们还将深入探讨Spring框架如何检测和解决循环依赖。

qq_46096136的博客 9466

Spring循环依赖

循环依赖,其实就是循环引用,就是两个或者两个以上的 Bean 互相引用对方,最终形成一个闭环,如 A 依赖 B,B 依赖 C,C 依赖 A。结果:需要注意的是本例中启动时是不会报错的(因为非单例Bean默认不会初始化,而是使用时才会初始化),所以很简单咱们只需要手动。对于构造器注入出现缓存依赖,Spring 是无法解决的,因为当前 Bean 还未实例化,无法提前暴露对象,所以只能抛出异常。)​:存储Bean的ObjectFactory,用于创建早期的Bean实例。

qq_40463629的博客 2146

面试必杀技:Spring循环依赖居然还有人讲不清楚?

面试必杀技:Spring循环依赖居然还有人讲不清楚? 干货分享最近将个人学习笔记整理成册,使用PDF分享主要包含了Java基础,数据结构,jvm,多线程等等,由于篇幅有限,以下只展示小部分面试题, 需要的朋友可以点一点领取:戳这里即可领取。。。 暗号:优快云 spring脑图 前言 Spring如何解决的循环依赖,是近两年流行起来的一道Java面试题。 其实笔者本人对这类框架源码题还是持一定的怀疑态度的。 如果笔者作为面试官,可能会问一些诸如“如果注入的属性为null,你会从哪几个方向去排查”这些场景题

a646705816的博客 1872

剖析Spring 循环依赖

循环依赖是指两个或多个 Spring Bean 之间存在相互引用的关系,形成一个依赖的闭环结构。这种依赖关系会导致 Bean 初始化过程中的"死锁"问题。简单循环依赖:Bean A 依赖 Bean B,同时 Bean B 又依赖 Bean A,形成 A ↔ B 的依赖环复杂循环依赖:Bean A 依赖 Bean B,Bean B 依赖 Bean C,而 Bean C 又依赖 Bean A,形成 A → B → C → A 的依赖链自环依赖:Bean A 直接或间接地依赖自身(较少见)本质分析。

Toroto5的博客 1563

Spring之循环依赖

Spring在Bean的实例化过程中,提供了对循环依赖的解决方案,但是这部分代码非常的生涩难懂,今天,我们就从一个Spring的源码来看看这个循环依赖到底是何方神圣! 首先Spring中的循环依赖到底是什么呢? 循环依赖就是循环引用,就是在类A中引用了类B,而类B中引用了类C,而类C中又引用了类A,如图: 图一 在图一中,我们可以看到A中存在属性B,B中存在属性C,而C中有又存在属...

Taylar_where的博客 9429

Spring之Bean循环依赖详解

今天要说的是spring中循环依赖的问题,最近有大量粉丝问这个问题,也是高薪面试中经常会被问到的一个问题。 关于循环依赖的问题,来感受一下连环炮,试试自己否可以过关斩将,轻松应对。 什么是循环依赖? 如何检测是否存在循环依赖? 如何解决循环依赖? 多例的情况下,循环依赖问题为什么无法解决? 单例的情况下,虽然可以解决循环依赖,是否存在其他问题? 为什么采用三级缓存解决循环依赖?如果直接将早期bean丢到二级缓存可以么? 前面4个ok的,超越了80

azhou的代码园 4709

Spring Bean 循环依赖详解

时序图帮助理解Spring Bean 循环依赖

分享Java,Rust相关技术 1505

Spring中的循环依赖问题

浅谈spring中的循环依赖问题

AG.『Feng』的博客 3792
上一篇: 分析常见限流算法及手写三种(计数器、漏斗、令牌桶)代码实现
下一篇: 来看看你是不是真的了解 RSA 加密算法,查漏补缺!
Java_LingFeng
博客等级 码龄4年 505粉丝 259原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值