2022年5月17日 下午4:14 • 面试题 • 阅读 13  题外推荐  推荐一个“摸鱼程序员”聚集地 循环依赖问题全景图 什么是循环依赖问题? 类与类之间的依赖关系形成了闭环,就会导致循环依赖问题的产生。 比如下图中A类依赖了B类,B类依赖了C类,而最后C类又依赖了A类,这样就形成了循环依赖问题。 演示代码:  @Test public void test() throws Exception {  // 创建IoC容器,并进行初始化  String resource = "spring/spring-ioc-circular-dependency.xml";  ApplicationContext context = new ClassPathXmlApplicationContext(resource);  // 获取ClassA的实例(此时会发生循环依赖)  ClassA classA = (ClassA) context.getBean(ClassA.class); } 通过Spring IOC流程的源码分析循环依赖问题: 以上案例有几种循环依赖问题? 循环依赖问题在Spring中主要有三种情况: 通过构造方法进行依赖注入时产生的循环依赖问题。 通过setter方法进行依赖注入且是在多例(原型)模式下产生的循环依赖问题。 通过setter方法进行依赖注入且是在单例模式下产生的循环依赖问题。 注意:在Spring中,只有【第三种方式】的循环依赖问题被解决了,其他两种方式在遇到循环依赖问题时都会产生异常。 其实也很好解释: 第一种构造方法注入的情况下,在new对象的时候就会堵塞住了,其实也就是”先有鸡还是先有蛋“的历史难题。 第二种setter方法&&多例的情况下,每一次getBean()时,都会产生一个新的Bean,如此反复下去就会有无穷无尽的Bean产生了,最终就会导致OOM问题的出现。 如何解决循环依赖问题? 那Spring到底是如何解决的setter方法依赖注入引起的循环依赖问题呢?请看下图(其实主要是通过两个缓存来解决的): Spring三大缓存介绍 Spring中有三个缓存,用于存储单例的Bean实例,这三个缓存是彼此互斥的,不会针对同一个Bean的实例同时存储。 推荐:Java进阶视频资源 如果调用getBean,则需要从三个缓存中依次获取指定的Bean实例。读取顺序依次是一级缓存–>二级缓存–>三级缓存 一级缓存:Map singletonObjects 第一级缓存的作用? 用于存储单例模式下创建的Bean实例(已经创建完毕)。 该缓存是对外使用的,指的就是使用spring框架的程序员。 存储什么数据? K:bean的名称 V:bean的实例对象(有代理对象则指的是代理对象,已经创建完毕) 第二级缓存:Map earlySingletonObjects 第二级缓存的作用? 用于存储单例模式下创建的Bean实例(该Bean被提前暴露的引用,该Bean还在创建中)。 该缓存是对内使用的,指的就是Spring框架内部逻辑使用该缓存。 为了解决第一个classA引用最终如何替换为代理对象的问题(如果有代理对象)请爬楼参考演示案例 存储什么数据? K:bean的名称 V:bean的实例对象(有代理对象则指的是代理对象,该Bean还在创建中) 第三级缓存:Map> singletonFactories 第三级缓存的作用? 通过ObjectFactory对象来存储单例模式下提前暴露的Bean实例的引用(正在创建中)。 该缓存是对内使用的,指的就是Spring框架内部逻辑使用该缓存。 此缓存是解决循环依赖最大的功臣 存储什么数据? K:bean的名称 V:ObjectFactory,该对象持有提前暴露的bean的引用 为什么第三级缓存要使用ObjectFactory?需要提前产生代理对象。 什么时候将Bean的引用提前暴露给第三级缓存的ObjectFactory持有?时机就是在第一步实例化之后,第二步依赖注入之前,完成此操作。 总结 以上就是Spring解决循环依赖的关键点!总结来说,就是要搞清楚以下几点: 搞清楚Spring三级缓存的作用? 搞清楚第三级缓存中ObjectFactory的作用? 搞清楚为什么需要第二级缓存? 搞清楚什么时候使用三级缓存(添加和查询操作)? 搞清楚什么时候使用二级缓存(添加和查询操作)? 当目标对象产生代理对象时,Spring容器中(第一级缓存)到底存储的是谁? 感谢阅读,希望对你有所帮助 :)  来源:www.sxzhongrui.com/post/6895753832815394824 ●【练手项目】基于SpringBoot的ERP系统,自带进销存+财务+生产功能 ●分享一套基于SpringBoot和Vue的企业级中后台开源项目,代码很规范! ●能挣钱的,开源 SpringBoot 商城系统,功能超全,超漂亮! 与其在网上拼命找题? 不如马上关注我们~ PS:因为公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。点“在看”支持我们吧! 版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。 文章由半码博客整理,本文链接:https://www.sxzhongrui.com/index.php/post/8552.html