循环依赖
首先,我们先来了解一下什么是循环依赖。 循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错。
三种情况:
- 自己依赖自己的直接依赖
- 两个对象之间的直接依赖
- 多个对象之间的间接依赖
前面两种情况的直接循环依赖比较直观,非常好识别,但是第三种间接循环依赖的情况有时候因为业务代码调用层级很深,不容易识别出来
Spring如何解决循环依赖
1、能解决的依赖场景
单例的setter注入
解决方式为三级缓存
spring内部有三级缓存:
- singletonObjects 一级缓存,用于保存实例化、注入、初始化完成的bean实例
- earlySingletonObjects 二级缓存,用于保存实例化完成的bean实例
- singletonFactories 三级缓存,用于保存bean创建工厂,以便于后面扩展有机会创建代理对象。
综上,其实解决单例setter注入的循环依赖时,是将创建对象,与依赖注入的两件事情分开做了,当需要创建这个bean时,首先先将其工厂放到三级中,然后去寻找依赖,当这个依赖的创建循环到自己时,可以直接将三级中存储的取出来,虽然它现在只是个空壳,没有内部的依赖注入,但因为是单例,操作来操作去,a还是只有那个a,所以可以解决循环依赖问题。
2、不能解决的依赖场景
- 多例的setter注入
- 构造器注入
- DependsOn循环依赖