博客
关于我
图解Spring循环依赖,看过之后再也不怕面试被问到了!
阅读量:796 次
发布时间:2023-03-22

本文共 1142 字,大约阅读时间需要 3 分钟。

前言

Spring如何解决循环依赖,是近年来热门的Java面试题之一。笔者对这类框架源码题持有一定的怀疑态度,但作为面试官可能会出一些场景题,如“如果注入的属性为null,你会从哪些方向排查”。既然写了这篇文章,就闲话不说,来看看Spring是如何解决循环依赖的,以及循环依赖的本质是什么。

正文

循环依赖通常发生在默认单例Bean的属性注入中,例如几个Bean互相引用或甚至自己引用自己。原型Bean的场景则不支持循环依赖,通常会抛出BeanCurrentlyInCreationException。Spring默认单例的属性注入场景下如何支持循环依赖呢?

Spring解决循环依赖

Spring内部维护了三个Map,常被称为三级缓存。在DefaultSingletonBeanRegistry类中可以看到这三个Map:singletonObjectssingletonFactoriesearlySingletonObjects。后两个Map主要用于创建Bean的过程,完成后会被清空,最终Bean会存储在singletonObjects中。

这三个Map的作用类似于“三级缓存”,其中earlySingletonObjects用于存储Bean的早期引用,singletonFactories用于存储创建Bean的原始工厂方法,而singletonObjects则存储最终的单例Bean实例。Spring通过这三个Map协同工作,解决循环依赖问题。

循环依赖的本质

如果让你从零实现一个支持循环依赖的依赖注入框架,你会怎么做?假设需要将指定类实例化为单例,并注入类字段为单例,同时支持循环依赖。举个例子,类A中有字段B,类B中有字段A。这其实与two sum问题很相似。

two sum问题中,我们需要找到数组中两个数之和等于目标值的两个索引。这可以通过一次遍历和一个HashMap来实现:先将当前数存入HashMap,然后检查是否有与目标值相关的数已经存在于HashMap中。如果有,返回这两个数的索引;否则,将当前数存入HashMap。这种方法类似于Spring如何处理循环依赖:通过缓存(HashMap)记录已创建的Bean实例,当需要注入的Bean已经存在时,直接从缓存中取用;否则,创建新实例并注入。

这就是循环依赖的本质,而不是Spring如何解决循环依赖。理解这一点可以帮助我们更好地理解Spring的实现机制,而不是陷入阅读源码的泥潭。

结尾

如果你是上文提到的“陷入阅读源码泥潭”的读者,这篇文章或许能帮到你。如果你对Spring的复杂性有疑问,不妨跳出“牛角尖”,看看Java世界还有其他值得探索的领域。技术世界永远充满新鲜事物,保持好奇心是成长的关键。

转载地址:http://ddqfk.baihongyu.com/

你可能感兴趣的文章
Objective-C实现求两点间距离(附完整源码)
查看>>
Objective-C实现求中位数(附完整源码)
查看>>
Objective-C实现求中位数(附完整源码)
查看>>
Objective-C实现求众数(附完整源码)
查看>>
Objective-C实现求圆锥的体积(附完整源码)
查看>>
Objective-C实现求曲线在某点的导数(附完整源码)
查看>>
Objective-C实现求最大公约数 (GCD)的算法(附完整源码)
查看>>
Objective-C实现求梯形面积公式(附完整源码)
查看>>
Objective-C实现求模逆算法(附完整源码)
查看>>
Objective-C实现求正弦(附完整源码)
查看>>
Objective-C实现求矩阵对角线元素之和(附完整源码)
查看>>
Objective-C实现汉密尔顿循环算法(附完整源码)
查看>>
Objective-C实现波利比乌斯密码算法(附完整源码)
查看>>
Objective-C实现波雷费密码算法(附完整源码)
查看>>
Objective-C实现洗牌移位密码算法(附完整源码)
查看>>
Objective-C实现测试信用卡号码有效性credit card validator的算法(附完整源码)
查看>>
Objective-C实现海伦公式(附完整源码)
查看>>
Objective-C实现海伦公式(附完整源码)
查看>>
Objective-C实现消息队列(附完整源码)
查看>>
Objective-C实现消息队列(附完整源码)
查看>>