首页私人日誌手把手教你解决循环依赖的方法

手把手教你解决循环依赖的方法

admin 03-10 11:30 61次浏览

第一,循环依赖是什么?

类A依赖类B,类B也依赖类A,这种情况会导致循环依赖。

BeanA→BeanB→BeanA

以上是比较容易发现的循环依赖,也有更深层次的循环依赖。

BeanA→BeanB→BeanC→BeanD→BeanE→BeanA

Spring的循环依赖于

当Spring上下文加载所有bean时,它会尝试按照它们之间关系的顺序来创建。如果没有循环依赖,例如:

BeanA→BeanB→BeanC

首先,Spring将创建BeanC,然后创建BeanB(并将BeanC注入BeanB),最后创建BeanA(并将BeanB注入BeanA)。

但如果我们有循环依赖,Spring上下文不知道应该先创建哪一个Bean,因为它们是相互依赖的。在这种情况下,Spring会在加载上下文时抛出一个BeanCurrentlyInCreationException。

如果我们使用结构方法进行注入,就会遇到这样的情况。由于这是上下文加载,所以需要注入。

举个栗子

在组织类中,用户类需要调用方法,因此通过构造方法注入组织类。

@Service

public class UserService {

    

    private final DepartmentService departmentSerivce;

 

    /**

     * 通过构造方法注入DepartmentService类

     */

    @Autowired

    public UserSerivce(DepartmentService departmentService) {

        this.departmentService = departmentService;

    }

 

    public List<Department> list() {

        retern departmentService.list();

    }    

 

}


而组织类也刚好需要调用用户类里的方法,于是它也通过构造方法注入用户类。


@Service

public class DepartmentService {

    

    private final UserService userSerivce;

 

    /**

     * 通过构造方法注入UserService类

     */

    @Autowired

    public DepartmentSerivce(UserService userSerivce) {

        this.userSerivce = userSerivce;

    }

    

}



这种情况程序在编译时,就会报下面的错误


Description:

 

The dependencies of some of the beans in the application context form a cycle:

 

┌─────┐

|  userService defined in file [D:\Java\IdeaProjects\UserService.class]

↑     ↓

|  departmentService defined in file [D:\Java\IdeaProjects\DepartmentService.class]

└─────┘


现在我们可以为测试编写一个配置类,让我们称之为‎‎TestConfig‎‎,它指定要扫描组件的基本包。让我们假设我们的bean在包"‎‎com.baeldung.circulardependency‎‎"中定义:‎


@Configuration

@ComponentScan(basePackages = { "com.baeldung.circulardependency" })

public class TestConfig {

}


最后,我们可以编写一个 JUnit 测试来检查循环依赖关系。测试可以为空,因为在上下文加载期间将检测到循环依赖关系。‎


@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(classes = { TestConfig.class })

public class CircularDependencyTest {

 

    @Test

    public void givenCircularDependency_whenConstructorInjection_thenItFails() {

        // Empty test; we just want the context to load

    }

}


如果您尝试运行此测试,您将得到以下异常:‎

BeanCurrentlyInCreationException: Error creating bean with name 'UserService':

Requested bean is currently in creation: Is there an unresolvable circular reference?


EPC单机挂载UHOST-RSSD高速磁盘 绝密公式算单双准确率99_在线计划全天免费计划