您的位置:首页 > 编程语言 > Java开发

Spring解决循环依赖,你真的懂了吗?

2020-03-18 23:15 295 查看
## 导读 - 前几天发表的文章[SpringBoot多数据源动态切换](https://chenjiabing666.github.io/2020/03/12/SpringBoot%E6%95%B4%E5%90%88%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90%EF%BC%8C%E4%BD%A0%E4%BC%9A%E4%BA%86%E5%90%97%EF%BC%9F/)和[SpringBoot整合多数据源的巨坑](https://chenjiabing666.github.io/2020/03/18/SpringBoot%E6%95%B4%E5%90%88%E5%A4%9A%E6%95%B0%E6%8D%AE%E6%BA%90%E7%9A%84%E5%B7%A8%E5%9D%91/)中,提到了一个坑就是动态数据源添加@Primary接口就会造成循环依赖异常,如下图: ![微信所有码猿技术专栏](https://gitee.com/chenjiabing666/Blog-file/raw/master/circleex.png) - 这个就是典型的构造器依赖,详情请看上面两篇文章,这里不再详细赘述了。本篇文章将会从源码深入解析Spring是如何解决循环依赖的?为什么不能解决构造器的循环依赖? ## 什么是循环依赖 - 简单的说就是A依赖B,B依赖C,C依赖A这样就构成了循环依赖。 ![微信搜索码猿技术专栏](https://gitee.com/chenjiabing666/Blog-file/raw/master/15282870029143.jpg) - 循环依赖分为构造器依赖和属性依赖,众所周知的是Spring能够解决属性的循环依赖(set注入)。下文将从源码角度分析Spring是如何解决属性的循环依赖。 ## 思路 - 如何解决循环依赖,Spring主要的思路就是依据三级缓存,在实例化A时调用doGetBean,发现A依赖的B的实例,此时调用doGetBean去实例B,实例化的B的时候发现又依赖A,如果不解决这个循环依赖的话此时的doGetBean将会无限循环下去,导致内存溢出,程序奔溃。spring引用了一个早期对象,并且把这个"早期引用"并将其注入到容器中,让B先完成实例化,此时A就获取B的引用,完成实例化。 ## 三级缓存 - Spring能够轻松的解决属性的循环依赖正式用到了三级缓存,在AbstractBeanFactory中有详细的注释。 ```java /**一级缓存,用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用*/ private final Map
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: