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;
    }
}

 

posted @ 2023-08-11 11:11  Java小白的搬砖路  阅读(345)  评论(0编辑  收藏  举报