spring解决相互依赖的问题

本文介绍了Spring如何处理setter注入导致的循环依赖问题。通过提前暴露未完全初始化的bean到bean池,Spring能解决单例bean的循环依赖。然而,对于构造器依赖和prototype作用域的field属性注入的循环依赖,Spring无法处理,会抛出异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

spring解决相互依赖的问题

 

 

  1. 构造器循环依赖

@Service

public class A {      

public A(B b) {  }

 }

@Service

public class B {

      public C (C c) {  }

@Service

public class C {

      public A (A a) {  }

}

通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出BeanCurrentlyInCreationException异常表示循环依赖

 

描述:创建A类是,构造器需要B类,那将去创建B,在创建B时又发现需要A类,则又去创建C类,最终在创建C时发现又需要A,从而形成一个环,没办法创建。

 

原理:Spring容器将每一个正在创建的bean标识符放在一个“当前创建bean池”中,bean标识符创建过程中将一直保持在这个池中,因为如果在创建bean过程中发现自己已经在“当前创建bean池”中时,将会抛出BeanCurrentlyInCreationException异常表示循环依赖;而对于创建完毕的bean将从“当前创建bean池”中清除掉。

 

2 setter循环依赖

@Service

public class A1 {      

@Autowired      

private B1 b1; } 

@Service

public class B1 {      

@Autowired      

public C1 c1;

@Service

public class C1 {      

@Autowired 

public A1 a1;

 }

 

通过setter注入方式构成的循环依赖。

 

原理:对于setter注入造成的依赖是通过Spring容器提前暴露刚完成构造器注入但未完成其他步骤(比如setter注入)的bean来完成的,而且只能解决单例作用域的bean循环依赖。

 

 

3.field属性注入循环依赖(prototype)

@Service @Scope("prototype") public class A1 {       @Autowired       private B1 b1; }  @Service @Scope("prototype") public class B1 {       @Autowired       public C1 c1; }  @Service @Scope("prototype") public class C1 {       @Autowired  public A1 a1; }

报错

 

3.总结
Spring只能解决Setter方法注入的单例bean之间的循环依赖
ClassA依赖ClassBClassB又依赖ClassA,形成依赖闭环。Spring在获取ClassA的实例时,不等ClassA完成创建就将其曝光加入正在创建的bean缓存中。在解析ClassA的属性时,又发现依赖于ClassB,再次去获取ClassB,当解析ClassB的属性时,又发现需要ClassA的属性,但此时的ClassA已经被提前曝光加入了正在创建的bean的缓存中,则无需创建新的的ClassA的实例,直接从缓存中获取即可。从而解决循环依赖问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值