Spring框架中的循环依赖是指两个或多个Spring Bean相互依赖对方,形成一个闭环。Spring支持两种类型的循环依赖:
- 构造器循环依赖:发生在Bean的构造器中,Spring容器无法处理这种循环依赖。
- 字段注入循环依赖:发生在Bean的字段上,Spring容器可以通过三级缓存处理这种循环依赖。
以下是构造器循环依赖和字段注入循环依赖的示例代码。
构造器循环依赖示例
假设有两个Bean A
和 B
,它们在构造器中相互依赖:
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;
}
}
在Spring配置中:
@Configuration
public class AppConfig {
@Bean
public A a() {
return new A(b());
}
@Bean
public B b() {
return new B(a());
}
}
Spring容器在创建A
或B
时,会尝试创建另一个,从而形成循环,这将导致BeanCurrentlyInCreationException
异常。
字段注入循环依赖示例
如果A
和B
使用字段注入而不是构造器注入,Spring可以解决循环依赖:
public class A {
private B b;
@Autowired
public void setB(B b) {
this.b = b;
}
}
public class B {
private A a;
@Autowired
public void setA(A a) {
this.a = a;
}
}
在Spring配置中,无需特别配置,Spring会自动处理字段注入的循环依赖:
@Configuration
public class AppConfig {
@Bean
public A a() {
return new A();
}
@Bean
public B b() {
return new B();
}
}
在这种情况下,Spring容器会使用一个临时的Bean引用来满足A
对B
的依赖,然后再使用B
的完整实例来满足A
的依赖,从而打破循环。