Spring学习笔记_21——循环依赖

循环依赖

1. 介绍

在Spring中的循环依赖就是指一个或者多个Bean之间存在着互相依赖的关系,并且形成了循环调用。

例如:在Spring中,Bean-A依赖Bean-B,Bean-B又依赖Bean-A,Bean-A和Bean-B之间就形成了相互依赖的关系。在创建A对象时,发现A对象依赖了B对象,此时先去创建B对象;创建B对象时,发现B对象又依赖了A对象,此时又区创建A对象......形成死循环。

同理,在Spring中多个对象之间有可能存在循环依赖。

2. 循环依赖类型

  • 自我依赖:Bean自己依赖自己,从而形成的循环依赖,一般情况下不会发生这种循环依赖。
  • 直接依赖:一般时发生在两个对象之间,A依赖B、B依赖A
  • 间接依赖:一般是发生在三个或三个以上对象之间互相依赖的场景。A依赖B、B依赖C、C依赖A......

3. 循环依赖场景

  • 构造器循环依赖
    • 这种情况发生在两个或多个Bean在其构造函数中相互依赖对方。例如,BeanA的构造函数需要一个BeanB的实例,而BeanB的构造函数又需要一个BeanA的实例。
    • 结果 :Spring无法解决构造器循环依赖,因为这会导致死锁。当Spring尝试创建BeanA时,它会因为缺少BeanB而阻塞;同样,当Spring尝试创建BeanB时,它会因为缺少BeanA而阻塞。
  • Setter方法注入循环依赖:
    • 这种情况发生在两个或多个Bean在其setter方法或通过其他方法注入中相互依赖对方。例如,BeanA有一个setter方法需要一个BeanB的实例,而BeanB有一个setter方法需要一个BeanA的实例。
    • 结果:Spring可以解决Setter/方法注入循环依赖,因为它允许在Bean的属性被填充后再进行其他Bean的属性注入。

4. 解决方案

4.1 解决Setter方法注入循环依赖
  1. 三级缓存机制

    • 一级缓存(singletonObjects):存储已经完全初始化好的Bean实例。

    • 二级缓存(earlySingletonObjects):存储Bean的早期引用,这些Bean实例已经实例化但还未完成属性注入和初始化。

    • 三级缓存(singletonFactories):存储Bean工厂对象,用于创建二级缓存中的Bean实例。

  2. 解决过程

    • 当Spring容器开始创建一个Bean时,它会首先检查三级缓存中是否已经有这个Bean的工厂对象。如果有,说明这个Bean正在创建中,Spring容器会从三级缓存中获取工厂对象,创建Bean的早期引用,并将其放入二级缓存中。

    • 然后,Spring容器会继续处理这个Bean的属性注入。如果属性依赖其他Bean,Spring容器会尝试从二级缓存中获取这些Bean的早期引用,而不是等待它们完全初始化。

    • 当所有属性注入完成后,Spring容器会将Bean从二级缓存移动到一级缓存,并执行Bean的初始化方法。

    • 如果在属性注入过程中发现循环依赖,Spring容器可以利用二级缓存中的早期引用来解决这个问题,因为这些早期引用已经包含了部分初始化的数据

4.2 解决构造器循环依赖

对于构造器循环依赖,Spring没有内置的解决方案。解决这类问题的常见方法包括:

  • 重新设计组件:重新设计组件之间的依赖关系,避免构造器循环依赖。
  • 使用Setter注入:将构造器注入改为Setter注入,利用Spring的循环依赖解决方案。
  • 使用原型Bean:将其中一个Bean的scope设置为prototype,因为原型Bean在每次请求时都会创建新的实例,从而避免循环依赖。
相关推荐
hrrrrb9 分钟前
【Spring Security】Spring Security 概念
java·数据库·spring
小信丶9 分钟前
Spring 中解决 “Could not autowire. There is more than one bean of type“ 错误
java·spring
摇滚侠2 小时前
Spring Boot 3零基础教程,IOC容器中组件的注册,笔记08
spring boot·笔记·后端
bnsarocket4 小时前
Verilog和FPGA的自学笔记2——点亮LED
笔记·fpga开发·verilog·自学
程序员小凯5 小时前
Spring Boot测试框架详解
java·spring boot·后端
Larry_Yanan6 小时前
QML学习笔记(三十四)QML的GroupBox、RadioButton
c++·笔记·qt·学习·ui
im_AMBER6 小时前
杂记 14
前端·笔记·学习·web
程序员小凯6 小时前
Spring Boot缓存机制详解
spring boot·后端·缓存
hello 早上好7 小时前
深入 Spring 依赖注入底层原理
数据库·sql·spring
程序媛徐师姐7 小时前
Java基于SpringBoot的茶叶商城系统,附源码+文档说明
java·spring boot·java springboot·茶叶商城系统·java茶叶商城系统·茶叶·java茶叶商城