如何解决循环依赖


如何解决循环依赖


目录

toc


1、循环依赖定义

比如,有两个类,一个是A,另一个是BA的创建需要依赖于B的一个实例,而B又依赖于A的一个实例。

下面是一个简单的例子:

A 需要B 来完成它的工作。

B 也需要A 来完成它的工作。

现在创建一个A的实例:

  1. 开始创建A的一个实例。
  2. 但为了完成这个任务,需要先创建一个B的实例。
  3. 开始创建B的一个实例。
  4. 但是,为了完成B的实例,你又需要一个A的实例。
  5. 现在你回到了步骤1,形成了一个闭环。
@Component
public class A {
    @Autowired
    private B b;
    public A() {
        System.out.println("A 实例化");
    }
}

@Component
public class B {
    @Autowired
    private A a;
    public B() {
        System.out.println("B 实例化");
    }
}

循环依赖就像是一个家庭里的两个孩子A和B,他们都想玩同一个玩具,但规则是要等对方先玩完才轮到自己。
现在的问题是。
A说:“我要等B玩完才能玩”。
B同时也说:“我要等A玩完才能玩”。
结果就是,他们两个都在等对方先玩,但实际上没有一个人能开始玩,因为他们都没法满足“对方先玩”的那个前提条件。

2.循环依赖场景

在Spring框架中,循环依赖主要发生在三个层面:构造器注入、Setter注入以及字段注入。以下是场景的例子,使用类A和B来说明。

1.构造器注入
@Component
public class A {
    private B b;

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

@Component
public class B {
    private A a;

    @Autowired
    public B(A a) {
        this.a = a;
    }
}
2. Set注入

在Setter注入中,类A有一个设置类B实例的setter方法,类B有一个设置类A实例的setter方法。

@Component
public class A {
    private B b;
    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

@Component
public class B {
    private A a;
    @Autowired
    public void setA(A a) {
        this.a = a;
    }
}
3.字段注入
@Component
public class A {
    @Autowired
    private B b;
}

@Component
public class B {
    @Autowired
    private A a;
}
4.@Bean注解配置
@Configuration
public class AppConfig {

    @Bean
    public A a(B b) {
        return new A(b);
    }
    @Bean
    public B b(A a) {
        return new B(a);
    }
}

public class A {
    private B b;
    public A(B b) {
        this.b = b;
    }

}

public class B {
    private A a;
    public B(A a) {
        this.a = a;
    }
}

3.解决方案

1.set注入
@Component
public class A {
    private B b;
    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}

@Component
public class B {
    private A a;
    @Autowired
    public void setA(A a) {
        this.a = a;
    }
}
2.@Lazy注解

如果必须使用构造器注入,可以在构造器参数上使用@Lazy注解,这样Spring会在实际使用到B的时候才去创建B的实例。

@Component
public class A {
    private final B b;
    @Autowired
    public A(@Lazy B b) {
        this.b = b;
    }
}

@Component
public class B {
    private final A a;
    @Autowired
    public B(@Lazy A a) {
        this.a = a;
    }
}

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值