spring循环依赖

184 阅读2分钟

前言

关于spring循环依赖网上有太多的例子,本文只是简单的记录一下。本文默认读者熟悉spring核心之一控制反转和依赖注入

分析一下

bean循环依赖案例 在我们的开发过程中,我们基本上对循环依赖是无感且不用去考虑如何解决。如上图中ClassA使用属性注入了ClassB,ClassB使用属性注入了ClassA。如上图这就是产生了循环依赖,但是如果我们这样启动项目是能启动成功的。这是因为spring已经帮我们解决了部分产生循环依赖的问题。

首先图解一下spring加载bean流程 在这里插入图片描述 解决spring循环依赖很重要的一个思想就是一个中间态

Spring的三级缓存解决循环依赖的问题

  • singletonObjects:完成初始化的单例bean对象的单例池。这里的bean经历过实例化->属性填充->初始化以及各种后置处理(一级缓存);
  • earlySingletonObjects:存放早期曝光的bean 对象(完成实例化但是尚未填充属性和初始化)。仅仅能作为指针提前曝光,被其他bean所引用,用于解决循环依赖的(二级缓存);
  • singletonFactories:存放早期曝光的bean对象工厂(完成实例化但是尚未填充属性和初始化)。如果允许提前曝光(allowEarlyReference = true),Spring 会将实例化后的 bean 提前曝光,也就是把该 bean 转换 成 beanFactory 并加入到 singletonFactories(三级缓存);

图解 在这里插入图片描述 spring在默认情况下会对创建bean进行自然排序,所以在默认情况下A会有限创建

依赖情况依赖注入方式是否解决
类A和类B互相依赖互相采用setter注入
类A和类B互相依赖互相采用构造器注入
类A和类B互相依赖类A采用setter注入类B,类B采用构造器注入类A
类A和类B互相依赖类A采用构造器注入类B,类B采用setter注入类A
  • 所以spring只能解决setter注入的循环依赖是错误的
  • 三级缓存可以提高性能也是错误的(本文没有解析,请自行分析)
  • 最后虚心学习,共同进步 -_-