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

简介: Spring 如何解决循环依赖问题?

循环依赖问题在 Spring 中有三种情况:

(1)通过构造方法进行依赖注入时产生的循环依赖问题

(2)通过 setter 方法进行依赖注入时且是在多例模式下产生的循环依赖问题

(3)通过 setter 方法进行依赖注入且是在单例模式下产生的循环依赖问题

在 spring 中只有第(3)种方式的循环依赖问题被解决了,其他两种方式在遇到循环依赖问题时都会产生异常,这是因为:

第一种:构造方法注入产生的循环依赖:当多个对象之间存在循环的引用关系时(也就是 A 类中注入 B 对象,同时 B 类中注入 A 对象),在初始化过程中,就会出现 “先有鸡还是先有蛋” 的问题。

@Lazy 注解:在构造方法上加上 @Lazy 注解解决构造方法造成的循环依赖问题。(本质上就是懒加载,先加载一个后加载一个)

第二种:setter 方法(多例)的情况下,每一次获取 bean 时就会产生一个新的 bean,一直下去就会产生无数的 Bean,最终会导致 OOM(内存溢出)问题的出现

Spring 在单例模式下的 setter 方法注入引起的循环依赖问题,主要是通过二级缓存和三级缓存来解决的,其中三级缓存是主要贡献者。

二级缓存会保存 new 出来的不完整的对象,这样当单例池中找不到依赖的属性时,就可以先从二级缓存中获取到不完整的对象并完成对象创建,然后在后续的依赖注入过程中将单例池中对象的引用关系调整完成。

三级缓存中,如果引用的对象配置了 AOP,那在单例池中最终就会需要注入动态代理对象而不是原对象。而生成动态代理是要在对象初始化完成之后才开始的。所以 Spring 增加三级缓存,保存所有对象的动态代理配置信息。在发现有循环依赖时,会将这个对象的动态代理信息获取出来,提前进行 AOP,生成动态代理。

相关文章
|
1月前
|
缓存 架构师 Java
图解 Spring 循环依赖,一文吃透!
Spring 循环依赖如何解决,是大厂面试高频,本文详细解析,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
图解 Spring 循环依赖,一文吃透!
|
16天前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
38 2
|
3月前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
227 24
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
2月前
|
缓存 Java Spring
源码解读:Spring如何解决构造器注入的循环依赖?
本文详细探讨了Spring框架中的循环依赖问题,包括构造器注入和字段注入两种情况,并重点分析了构造器注入循环依赖的解决方案。文章通过具体示例展示了循环依赖的错误信息及常见场景,提出了三种解决方法:重构代码、使用字段依赖注入以及使用`@Lazy`注解。其中,`@Lazy`注解通过延迟初始化和动态代理机制有效解决了循环依赖问题。作者建议优先使用`@Lazy`注解,并提供了详细的源码解析和调试截图,帮助读者深入理解其实现机制。
69 1
|
3月前
|
缓存 Java Spring
手写Spring Ioc 循环依赖底层源码剖析
在Spring框架中,IoC(控制反转)是一个核心特性,它通过依赖注入(DI)实现了对象间的解耦。然而,在实际开发中,循环依赖是一个常见的问题。
46 4
|
4月前
|
存储 缓存 Java
面试问Spring循环依赖?今天通过代码调试让你记住
该文章讨论了Spring框架中循环依赖的概念,并通过代码示例帮助读者理解这一概念。
面试问Spring循环依赖?今天通过代码调试让你记住
|
4月前
|
缓存 Java Spring
spring如何解决循环依赖
Spring框架处理循环依赖分为构造器循环依赖与setter循环依赖两种情况。构造器循环依赖不可解决,Spring会在检测到此类依赖时抛出`BeanCurrentlyInCreationException`异常。setter循环依赖则通过缓存机制解决:利用三级缓存系统,其中一级缓存`singletonObjects`存放已完成的单例Bean;二级缓存`earlySingletonObjects`存放实例化但未完成属性注入的Bean;三级缓存`singletonFactories`存放创建这些半成品Bean的工厂。
|
4月前
|
Java Spring 容器
循环依赖难破解?Spring Boot神秘武器@RequiredArgsConstructor与@Lazy大显神通!
【8月更文挑战第29天】在Spring Boot应用中,循环依赖是一个常见问题。当两个或多个Bean相互依赖形成闭环时,Spring容器会陷入死循环。本文通过对比@RequiredArgsConstructor和@Lazy注解,探讨它们如何解决循环依赖问题。**@RequiredArgsConstructor**:通过Lombok生成包含final字段的构造函数,优先通过构造函数注入依赖,简化代码但可能导致构造函数复杂。**@Lazy**:延迟Bean的初始化,直到首次使用,打破创建顺序依赖,增加灵活性但可能影响性能。根据具体场景选择合适方案可有效解决循环依赖问题。
157 0
|
5月前
|
缓存 Java 开发者
Spring循环依赖问题之Spring循环依赖如何解决
Spring循环依赖问题之Spring循环依赖如何解决
|
4月前
|
前端开发 Java 测试技术
单元测试问题之在Spring MVC项目中添加JUnit的Maven依赖,如何操作
单元测试问题之在Spring MVC项目中添加JUnit的Maven依赖,如何操作