spring循环依赖
关于spring循环依赖网上有太多的例子,本文只是简单的记录一下。本文默认读者熟悉spring核心之一控制反转和依赖注入
在我们的开发过程中,我们基本上对循环依赖是无感且不用去考虑如何解决。如上图中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注入的循环依赖是错误的
- 三级缓存可以提高性能也是错误的(本文没有解析,请自行分析)
- 最后虚心学习,共同进步。-_-