nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException(Spring循环依赖问题)

简介: nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException(Spring循环依赖问题)

1:问题

最近启动项目时候,遇到如下报错

nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'stockReceiptManager': Bean with name 'stockReceiptManager' has been injected


the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.

 

2:分析原因

后来在网上找了半天说是依赖循环,检查了一下代码,确实存在循环依赖的现象

spring默认是支持循环依赖,allowCircularRefrence默认为true。也可以手动设置applicationContext.setAllowCircularReferences(false); 产生这个问题原因:in its raw version as part of a circular reference, but has eventually been wrapped.应该是项目中对某个类的方法开启异步@Async导致

 

3:解释循环依赖

首先说一下什么是依赖循环,比如:我现在有一个ServiceA需要调用ServiceB的方法,那么ServiceA就依赖于ServiceB,那在ServiceB中再调用ServiceA的方法,就形成了循环依赖。Spring在初始化bean的时候就不知道先初始化哪个bean就会报错。


由于类A通过构造注入需要类B的实例,而类B通过构造注入需要类B的实例,二者之间相互注入,导致循环引用抛出异常,这是一个典型的先有鸡还是先有蛋的故事。所以在使用spring配置类的循环依赖的关系时,应当尽量避免使用构造注入,而是使用setter注入。

public class ClassA {
    @Autowired
    ClassB classB;
}
 
public class ClassB {
    @Autowired
    ClassA classA ;
} 

那如何解决循环依赖,当然最好的方法是重构你的代码,进行解耦,但是重构不是一时的事情,那就使用下面的方法:

方法一:

<bean id="ServiceDependent1" class="org.xyz.ServiceDependent1" lazy-init="true">
      <constructor-arg ref="Service"/>
</bean>
    
<bean id="ServiceDependent2" class="org.xyz.ServiceDependent2" lazy-init="true">
      <constructor-arg ref="Service"/>
</bean>

方法二:

在你的配置文件中,在互相依赖的两个bean的任意一个加上lazy-init属性。

在你注入bean时,在互相依赖的两个bean上加上@Lazy注解也可以。

以上两种方法都能延迟互相依赖的其中一个bean的加载,从而解决循环依赖的问题。

    @Autowired
    @Lazy
    private ClassA classA;
 
    @Autowired
    @Lazy
    private ClassB classB;

相关文章
|
5月前
|
监控 安全 Java
解决 Spring Boot 中 SecurityConfig 循环依赖问题的详解
本文详细解析了在 Spring Boot 中配置 `SecurityConfig` 时可能遇到的循环依赖问题。通过分析错误日志与代码,指出问题根源在于 `SecurityConfig` 类中不当的依赖注入方式。文章提供了多种解决方案:移除 `configureGlobal` 方法、定义 `DaoAuthenticationProvider` Bean、使用构造函数注入以及分离配置类等。此外,还讨论了 `@Lazy` 注解和允许循环引用的临时手段,并强调重构以避免循环依赖的重要性。通过合理设计 Bean 依赖关系,可确保应用稳定启动并提升代码可维护性。
418 0
|
10月前
|
缓存 架构师 Java
图解 Spring 循环依赖,一文吃透!
Spring 循环依赖如何解决,是大厂面试高频,本文详细解析,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
图解 Spring 循环依赖,一文吃透!
|
9月前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
198 2
|
12月前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
677 24
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
11月前
|
缓存 Java Spring
源码解读:Spring如何解决构造器注入的循环依赖?
本文详细探讨了Spring框架中的循环依赖问题,包括构造器注入和字段注入两种情况,并重点分析了构造器注入循环依赖的解决方案。文章通过具体示例展示了循环依赖的错误信息及常见场景,提出了三种解决方法:重构代码、使用字段依赖注入以及使用`@Lazy`注解。其中,`@Lazy`注解通过延迟初始化和动态代理机制有效解决了循环依赖问题。作者建议优先使用`@Lazy`注解,并提供了详细的源码解析和调试截图,帮助读者深入理解其实现机制。
555 1
|
12月前
|
缓存 Java Spring
手写Spring Ioc 循环依赖底层源码剖析
在Spring框架中,IoC(控制反转)是一个核心特性,它通过依赖注入(DI)实现了对象间的解耦。然而,在实际开发中,循环依赖是一个常见的问题。
105 4
|
存储 缓存 Java
面试问Spring循环依赖?今天通过代码调试让你记住
该文章讨论了Spring框架中循环依赖的概念,并通过代码示例帮助读者理解这一概念。
面试问Spring循环依赖?今天通过代码调试让你记住
|
缓存 Java 开发工具
【spring】如何解决循环依赖
【spring】如何解决循环依赖
517 56
|
缓存 Java Spring
spring如何解决循环依赖
Spring框架处理循环依赖分为构造器循环依赖与setter循环依赖两种情况。构造器循环依赖不可解决,Spring会在检测到此类依赖时抛出`BeanCurrentlyInCreationException`异常。setter循环依赖则通过缓存机制解决:利用三级缓存系统,其中一级缓存`singletonObjects`存放已完成的单例Bean;二级缓存`earlySingletonObjects`存放实例化但未完成属性注入的Bean;三级缓存`singletonFactories`存放创建这些半成品Bean的工厂。
176 2
|
缓存 Java 开发者
Spring循环依赖问题之Spring循环依赖如何解决
Spring循环依赖问题之Spring循环依赖如何解决

热门文章

最新文章