Spring构造器注入产生的循环依赖以及解决办法
一、循环依赖描述
问题描述:Bean A依赖B,Bean B依赖A,这种情况下即为循环依赖,如下:
Bean A --> Bean B --> Bean A
导致问题:当存在循环依赖时,Spring将无法决定先创建哪个bean,这种情况下,Spring将产生异常BeanCurrentlyInCreationException。
二、构造器循环依赖复现
@Component
@Slf4j
public class E1 {
private E2 e2;
public E1(E2 e2) {
log.info("E2({})", e2);
this.e2 = e2;
}
}
@Component
@Slf4j
public class E2 {
private E1 e1;
public E2(E1 e1) {
log.info("E1({})", e1);
this.e1 = e1;
}
}
启动项目报错:
*************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: ┌─────┐ | e1 defined in file [F:\StudyProject\example-springboot-demo\springboot-demo\target\classes\com\zhixi\config\E1.class] ↑ ↓ | e2 defined in file [F:\StudyProject\example-springboot-demo\springboot-demo\target\classes\com\zhixi\config\E2.class] └─────┘
三、如何解决构造器循环依赖
1、@Lazy注解
对E2进行延迟加载:
@Component
@Slf4j
public class E1 {
private E2 e2;
public E1(@Lazy E2 e2) {
this.e2 = e2;
}
}
@Component
@Slf4j
public class E2 {
private E1 e1;
public E2(E1 e1) {
this.e1 = e1;
}
}
2、使用对象工厂:ObjectFactory
@Component
@Slf4j
public class E1 {
private ObjectFactory<E2> e2;
public E1(ObjectFactory<E2> e2) {
this.e2 = e2;
}
}
@Component
@Slf4j
public class E2 {
private E1 e1;
public E2(E1 e1) {
this.e1 = e1;
}
}
3、使用Provider接口:实质也是一个对象工厂
需要在pom.xml中添加pom:
<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
代码如下:
import org.springframework.stereotype.Component;
import javax.inject.Provider;
@Component
public class E1 {
private Provider<E2> e2;
public E1(Provider<E2> e2) {
this.e2 = e2;
}
}
@Component
public class E2 {
private E1 e1;
public E2(E1 e1) {
this.e1 = e1;
}
}

浙公网安备 33010602011771号