spring循环依赖

概述

循环依赖是指在依赖注入的过程中,两个或多个 Bean 互相依赖对方,形成一个闭环。这会导致在创建这些 Bean 时,容器无法决定哪个 Bean 应该先实例化,从而造成无限循环或失败。

示例:

假设有两个类 A 和 B:

  • A 依赖于 B。
  • B 依赖于 A。

在这种情况下,当容器试图创建 A 时,需要先创建 B,但 B 又需要 A,这就形成了循环依赖。

解决方案:

  1. 构造函数注入:避免使用构造函数注入,改用属性注入或方法注入。
  2. 使用 @Lazy 注解:可以在 Spring 中标记某个 Bean 为懒加载,这样在首次使用时才会创建 Bean,打破循环依赖。
  3. 将依赖关系调整为非循环:重新设计类之间的依赖关系,以消除循环。

循环依赖会导致性能问题或启动失败,因此在设计系统时需要谨慎处理。

循环依赖示例

1. 循环依赖的代码:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
class A {
    private final B b;

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

    public void doSomething() {
        System.out.println("A is doing something with B");
    }
}

@Component
class B {
    private final A a;

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

    public void doSomething() {
        System.out.println("B is doing something with A");
    }
}

在这个例子中,类 A 依赖于类 B,而类 B 又依赖于类 A,这就形成了循环依赖。

解决方案

2. 使用属性注入解决循环依赖:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
class A {
    private B b;

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

    public void doSomething() {
        System.out.println("A is doing something with B");
    }
}

@Component
class B {
    private A a;

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

    public void doSomething() {
        System.out.println("B is doing something with A");
    }
}

通过使用属性注入(setter 注入),我们可以解决循环依赖的问题。Spring 可以先实例化 AB,然后再通过 setter 方法注入依赖。

3. 使用 @Lazy 注解解决循环依赖:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

@Component
class A {
    private final B b;

    @Autowired
    public A(@Lazy B b) {
        this.b = b;
    }

    public void doSomething() {
        System.out.println("A is doing something with B");
    }
}

@Component
class B {
    private final A a;

    @Autowired
    public B(@Lazy A a) {
        this.a = a;
    }

    public void doSomething() {
        System.out.println("B is doing something with A");
    }
}

在这个例子中,通过在构造函数中使用 @Lazy 注解,Spring 将在实际需要使用 BA 时才创建对应的实例,从而打破了循环依赖。

依赖注入方法

参考2.3节:https://blog.youkuaiyun.com/qq_37398465/article/details/137465288

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值