当前位置: 首页 > article >正文

spring如何解决循环依赖的 ?

循环依赖(Circular Dependency)是指在 Spring 中,多个 Bean 互相依赖,形成了一个闭环,导致无法正常创建和注入 Bean 的情况。简而言之,就是两个或多个 Bean 互相需要对方,导致循环引用。
假设有两个类 A 和 B,其中 A 依赖 B,B 又依赖 A,形成一个循环依赖。

@Component
public class A {
    @Autowired
    private B b;

    public void show() {
        System.out.println("Class A");
    }
}

@Component
public class B {
    @Autowired
    private A a;

    public void display() {
        System.out.println("Class B");
    }
}

在上述代码中,A 依赖 B,同时 B 也依赖 A。这种情况下,Spring 在创建这两个 Bean
时,会遇到问题,因为它无法决定应该先实例化 A 还是 B。 Spring 通过 三级缓存(three-level
cache)来解决循环依赖的问题。它使用的策略是 构造器注入 会导致循环依赖错误,而 Setter 注入 和 字段注入
由于有反射机制,会较为优雅地解决这一问题。

Spring 的三级缓存:
一级缓存(Singleton Objects Cache):存储已经创建的 Bean。
二级缓存(Early Singleton Objects Cache):存储早期暴露的 Bean。这个缓存中的 Bean 是尚未完全初始化的 Bean,但是可以满足依赖注入。
三级缓存(Raw Singleton Cache):是原始的、未完全处理的 Bean,类似于一个“占位符” Bean。
当 Spring 创建一个 Bean 时,如果遇到循环依赖的情况,会采取以下策略:
构造器注入:会抛出 BeanCurrentlyInCreationException 异常,因为构造器注入要求 Bean 必须完全初始化完毕才能注入依赖。
Setter 注入:Spring 会在二级缓存中暂时存放这个 Bean,直到其他依赖被注入完成,后续将继续完成其依赖注入。

1、通过 Setter 注入解决循环依赖

@Component
public class A {
    private B b;

    @Autowired
    public void setB(B b) {
        this.b = b;
    }

    public void show() {
        System.out.println("Class A");
    }
}

@Component
public class B {
    private A a;

    @Autowired
    public void setA(A a) {
        this.a = a;
    }

    public void display() {
        System.out.println("Class B");
    }
}

在这种情况下,Spring 会通过 setter 方法来注入依赖,避免了构造器注入时的死循环,最终能够完成 Bean 的初始化。

循环依赖问题通常发生在 构造器注入 的情况下。为了避免这种问题,建议使用 Setter 注入 或 字段注入,这样可以让 Spring
使用二级缓存暂时保存未完成的 Bean,直到所有依赖注入完成。


http://www.kler.cn/a/577237.html

相关文章:

  • 基于Asp.net的教学管理系统
  • 互动游戏开发新趋势:弹幕游戏源码与H5游戏源码开发的融合与创新
  • 【redis】全局命令exists、del、expire、ttl(惰性删除和定期删除)
  • Mysql的行级锁到底锁住了哪些行
  • 安装微软最新原版系统,配置好系统驱动并保留OOBE全新体验
  • 文件与目录权限
  • centos 安装composer 教程
  • 求最大公约数问题(信息学奥赛一本通-1207)
  • VS2022中使用EntityFrameworkCore连接MySql数据库方法
  • 计算机毕业设计Python+DeepSeek-R1大模型微博舆情分析系统 微博舆情预测 微博爬虫 微博大数 据(源码+LW文档+PPT+详细讲解)
  • WebSocket(WS)协议系列(三)加密
  • name ‘bare_metal_version‘ is not mamba_ssm安装
  • 国产化板卡设计原理图:2274-基于FMC接口的JFM7VX690T36的3U VPX信号处理板
  • Unity--Cubism Live2D模型使用
  • [数据结构]栈和队列
  • 指令的旋律:走进Linux系统开发工具,体悟Ubuntu系统下软件包管理器的奥秘
  • OpenHarmony AI服务 - Neural Network Runtime设备接入指导
  • 使用Node.js从零搭建DeepSeek本地部署(Express框架、Ollama)
  • Django小白级开发入门
  • 设计模式文章汇总-Golang语言实现