深入理解Spring中的循环依赖

 更新时间:2018年05月17日 10:10:26   作者:BeginnerH  
Spring在注入bean的时候会做循环依赖检查,下面这篇文章主要给大家介绍了关于Spring中循环依赖的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起看看吧

循环依赖

 定义: 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比方CircularityA引用CircularityB,CircularityB引用CircularityC,CircularityC引用CircularityA。形成一个环状引用关系。

在使用Spring时,如果主要采用基于构造器的依赖注入方式,则可能会遇到循环依赖的情况,简而言之就是Bean A的构造器依赖于Bean B,Bean B的构造器又依赖于Bean A。在这种情况下Spring会在编译时抛出BeanCurrentlyInCreationException。

Class A

@Component
public class ClassA {
 private ClassB classB;
 @Autowired
 public ClassA(ClassB classB) {
  this.classB = classB;
 }

 public void printClass() {
  System.out.println("Class A = " + this);
  System.out.println("Class B = " + classB);
 }
}

Class B

@Component
public class ClassB {
 private ClassA classA;
 @Autowired
 public ClassB(ClassA classA) {
  this.classA = classA;
 }

 public void printClass() {
  System.out.println("Class A = " + classA);
  System.out.println("Class B = " + this);
 }
}

测试

@ContextConfiguration(classes = {ClassA.class, ClassB.class})
@RunWith(SpringRunner.class)
public class MyTest {
 @Autowired
 private ClassA classA;
 @Autowired
 private ClassB classB;

 @Test
 public void name() {
  classA.printClass();
  classB.printClass();
 }
}

原因

这时候运行测试就会发现抛出了BeanCurrentlyInCreationException异常。产生这种情况的原因是,Spring在创建Bean时,会首先实例化对象,然后再注入依赖。假设Spring首先创建Class A,那么就会发现在构造器里有Class B的依赖,所以就会转去创建Class B,又在Class B的构造器里发现了对Class A的依赖,而此时Class A是还未初始化完的,因此又会转去创建Class A,这样就陷入了死循环。

解决方法

换成基于setter的依赖注入即可解决这个问题。因为基于setter的依赖注入会首先调用默认构造函数来实例化对象,然后再调用setter实现依赖注入。这样在对象实例化的阶段就没有了任何依赖,因此Class A实例化完成后再调用Class B,Class B实例化完成后开始设值,而这时Class A已经是实例化完成了的,所以可以成功引用到Class A。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

相关文章

  • Java并发编程同步器CountDownLatch

    Java并发编程同步器CountDownLatch

    这篇文章主要介绍了Java并发编程同步器CountDownLatch,文章基于Java并发编程的相关资料展开具有一定的参考价值,需要的小伙伴可以参考一下
    2022-04-04
  • Java 简化正则表达式的使用

    Java 简化正则表达式的使用

    本篇文章主要介绍了Java 简化正则表达式使用的相关知识,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-04-04
  • SpringCache轻松启用Redis缓存的全过程

    SpringCache轻松启用Redis缓存的全过程

    Spring Cache是Spring提供的一种缓存抽象机制,旨在通过简化缓存操作来提高系统性能和响应速度,本文将给大家详细介绍SpringCache如何轻松启用Redis缓存,文中有详细的代码示例供大家参考,需要的朋友可以参考下
    2024-07-07
  • SpringBoot集成redis的示例代码

    SpringBoot集成redis的示例代码

    redis想必小伙伴们即使没有用过,也是经常听到的,在工作中,redis用到的频率非常高,本文主要介绍了SpringBoot集成redis,感兴趣的可以参考一下
    2021-10-10
  • 新手Hadoop安装 环境搭建

    新手Hadoop安装 环境搭建

    这篇文章主要介绍了Hadoop的安装与环境搭建教程图解,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下,希望能给您带来帮助
    2021-06-06
  • Java+MyBatis+MySQL开发环境搭建流程详解

    Java+MyBatis+MySQL开发环境搭建流程详解

    Java的MyBatis框架提供了强大的数据库操作支持,这里我们先在本地的开发环境中上手,来看一下Java+MyBatis+MySQL开发环境搭建流程详
    2016-06-06
  • IntelliJ IDEA 2021.1 推出语音、视频功能,边写代码边聊天(功能超级强大)

    IntelliJ IDEA 2021.1 推出语音、视频功能,边写代码边聊天(功能超级强大

    这篇文章主要介绍了IntelliJ IDEA 2021.1 推出语音、视频功能,边写代码边聊天(功能超级强大),本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • Java实现图片裁剪功能的示例详解

    Java实现图片裁剪功能的示例详解

    这篇文章主要介绍了如何利用Java实现图片裁剪功能,可以将图片按照自定义尺寸进行裁剪,文中的示例代码讲解详细,感兴趣的可以了解一下
    2022-01-01
  • Java中的RPC框架Dubbo原理和机制详解

    Java中的RPC框架Dubbo原理和机制详解

    这篇文章主要介绍了Java中的RPC框架Dubbo原理和机制详解,Dubbo 是一款Java RPC框架,致力于提供高性能的 RPC 远程服务调用方案,作为主流的微服务框架之一,Dubbo 为开发人员带来了非常多的便利,需要的朋友可以参考下
    2024-01-01
  • java实现图片的上传与展示实例代码

    java实现图片的上传与展示实例代码

    这篇文章主要给大家介绍了关于java实现图片的上传与展示的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12

最新评论