大家好,欢迎来到Tlog4J课堂,我是Jensen。
面试官:Spring是如何解决循环依赖问题的?
候选人:Spring用了三级缓存来解决这个问题
面试官:能具体讲讲它的工作原理吗?
候选人:啊这……
Spring循环依赖其实是Spring当中非常典型的一个问题,也非常难的一道题,因为回答这个问题本身会特别绕,而且这不仅仅是一道题这么简单,它后面会引发面试官一系列的夺命连环问。
那今天咱一起把循环依赖涉及的问题认真梳理一遍。
循环依赖指的是多个对象之间的依赖关系形成一个闭环。
我们都知道,如果在代码中,把两个或者多个Bean相互之间去持有对方的引用,就会发生循环依赖,循环依赖会导致注入出现死循环,这是Spring发生循环依赖的一个原因。
第一种是互相依赖,也就是A依赖B,B又依赖A,它们之间形成了一个循环依赖:
第二种是三者之间的依赖,也就是A依赖B,B依赖C,C又依赖A,形成了一个循环依赖:
第三种是自我依赖,也就是说A与A之间形成的循环依赖。
现实中由于依赖层次深、关系复杂等因素, 导致循环依赖可能并不是那么一目了然。
三级缓存说白了就是三个Map容器,在框架里头这种Map容器是随处可见:
第一层: 初始化完备的单例bean。
/** Cache of singleton objects: bean name to bean instance. */
private final Map singletonObjects = new
ConcurrentHashMap<>(256);
第二层: 提前曝光的单例对象的Cache。
/** Cache of early singleton objects: bean name to bean instance. */
private final Map earlySingletonObjects = new
HashMap<>(16);
第三层: ObjectFactory工厂bean缓存, 存储实例化后的bean Factory。
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map> singletonFactories = new
HashMap<>(16);
循环依赖主要是解决这个“死循环”没有“出口”的问题,只要我们找到这个“出口”,循环依赖就能迎刃而解。
我们分四个步骤来说:
这里我们可以做一个总结:
如果还是不理解,可以多看几遍这个动图:
一句话概括:先让最底层对象完成初始化,通过三级缓存与二级缓存提前曝光创建中的Bean,让其他Bean率先完成初始化。
有四种情况是无法解决的:
其实,很多同学回答这个问题的时候也都知道,Spring就是使用三级缓存来处理这个问题,但是回答这个问题的难点在于,很多同学对这个问题理解不透,所以当你想要在短时间内向面试官解释清楚这个问题的时候,就会觉得有点条理不清。
以上这些都是从底层原理升华而来的具体问题,通常互联网大厂面试都是按这个套路,包括说很多基础知识像JVM、NIO、MQ等等这些也都是一样的——面试官先从框架的工作原理入手,考察你对框架原理的理解,最后再找一些实际的问题,考你对这种技术栈的综合的掌握能力,能不能解决实际的问题。
OK,回答好这个问题,关乎于你对Spring框架是否有深刻的理解,相信大家再次总结完后会有所收获。
当前标题:Spring循环依赖的“夺命连环问”,你能招架几波?
文章转载:http://www.csdahua.cn/qtweb/news29/431379.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网