什么是循环依赖
在Spring中,如果一个bean尝试将自身引用注入到自身中,通常会引发循环依赖。 例如两个Bean,A依赖B,B依赖A就构成了循环依赖;同样,如果在A中注入A表示A依赖A,同样构成循环依赖;
Spring如何解决循环依赖
循环依赖的底层原理是spring通过三级缓存实现:
- 一级缓存:这个缓存是单例bean的最终缓存,也叫做单例池
- 三级缓存:存放创建对象的工厂,用来创建对象,内部是一个Lambda表达式;
- 原理:
1、当创建A时,实例化后立即将其工厂放入三级缓存
2、接着对A进行字段填充,当A需要注入B时,而容器中没有B的bean,于是开始创建B
3、此时发现B也依赖于A,B需要注入A时,这时可以从三级缓存获取A的工厂对象(这个找的过程是从一级缓存中开始找,直到找到为止),创建提前曝光的A并放入二级缓存
4、B完成初始化后放入一集缓存,回到A的创建流程
5、A从一级缓存获取B完成注入,最终A也完成初始化并一并放入一级缓存。
6、至此循环依赖成功解决,A和B都完成了创建;
应用
虽然spring的三级缓存能够解决大部分的循环依赖问题,但是在实际使用过程中,尽量从根源上避免循环依赖的产生,一方面可以通过调用mapper层直接操作数据库,另一方面也可以在新开一个service层,防止循环依赖额产生;