大家好,我是小米,今天我们来聊聊 Spring 框架中的一个重要话题:循环依赖。在开发中,我们可能会遇到这样的问题:两个或多个 bean 之间相互依赖,导致创建对象时出现死循环。那么,Spring 是如何解决这个问题的呢?
(资料图片)
什么是循环依赖
在 Spring 中,bean 之间的依赖关系可以通过构造函数注入、Setter 注入、接口注入等方式实现。当两个或多个 bean 相互依赖时,就会形成循环依赖。比如,bean A 依赖于 bean B,而 bean B又依赖于 bean A,这就是循环依赖。
Spring 如何解决循环依赖
Spring使用“三级缓存”来解决循环依赖的问题。三级缓存指的是singletonObjects、earlySingletonObjects和singletonFactories三个Map。
在Spring创建对象时,会先检查 singletonObjects 中是否已经存在该对象的实例,如果存在,则直接返回该实例;如果不存在,则检查 earlySingletonObjects 中是否已经存在该对象的“提前曝光”的代理对象,如果存在,则返回该代理对象,否则就调用singletonFactories 中存储的工厂方法来创建该对象的实例,并将其放入 earlySingletonObjects 中,同时存储一个 Factory 对象到singletonFactories 中。
当对象创建完成之后,就会从 earlySingletonObjects中 移除该对象的代理对象,将完整的对象实例放入 singletonObjects 中,并清空 singletonFactories中的Factory 对象。这样,下次获取该对象的实例时,就可以直接从 singletonObjects 中获取了。
三级缓存是如何解决循环依赖
当出现循环依赖时,Spring 会将正在创建的对象提前曝光,也就是将一个代理对象放到 earlySingletonObjects 中,然后在创建对象时,将代理对象注入到另一个需要依赖该对象的 bean 中。这样,当需要使用该对象时,就可以从 earlySingletonObjects 中获取到代理对象,避免了死循环的出现。
缓存为什么是三级
三级缓存可以保证对象的单例性,同时也可以解决循环依赖的问题。而单例对象的创建和获取是很频繁的操作,所以使用三级缓存可以提高效率。
缓存的放置时间和删除时间
三级缓存:当 Spring 创建一个bean的实例时,会将其放入singletonFactories中,这个操作是在createBeanInstance之后完成的。同时,也会将该 bean 的工厂方法放入singletonFactories中。这样,当需要获取该 bean 的实例时,就可以从 singletonFactories 中获取到其对应的工厂方法。
二级缓存:当 Spring 从 singletonFactories 中获取到一个bean 的工厂方法后,会通过该工厂方法创建该 bean 的实例,并将其放入 earlySingletonObjects 中。同时,也会将其代理对象放入 earlySingletonObjects 中。
在后续创建依赖该 bean 的其他 bean 时,如果需要获取该bean 的实例,就会从 earlySingletonObjects 中获取到其代理对象。在第一次从 earlySingletonObjects 中获取到该代理对象时,Spring 会判断该对象是代理对象还是普通对象,如果是代理对象,则会将其替换为其对应的普通对象,并从 earlySingletonObjects 中删除该代理对象。
一级缓存:当Spring创建完一个bean的完整实例后,会将其放入 singletonObjects 中,并从 earlySingletonObjects中删除其对应的代理对象和工厂方法。同时,也会将其对应的bean的依赖项从 dependencyCheck 中移除。这样,下次获取该bean的实例时,就可以直接从 singletonObjects 中获取了。
提前曝光来解决循环依赖(不推荐)
除了三级缓存之外,提前曝光是 Spring 解决循环依赖问题的重要手段之一。当 Spring 创建一个 bean 的实例时,如果检测到其依赖了另一个正在创建的 bean,则会将其提前曝光,即将一个代理对象放入 earlySingletonObjects 中,以便在后续创建依赖该 bean 的其他 bean 时,可以直接使用其代理对象,避免了死循环的出现。不过,提前曝光的方法需要手动配置,比较麻烦,所以一般情况下,我们都会使用 Spring 提供的三级缓存来解决循环依赖的问题。
END
总的来说,Spring 是一个非常优秀的 Java 框架,它不仅提供了依赖注入和 AOP 等常用功能,还能够很好地解决循环依赖的问题。而这些都离不开 Spring 框架底层的设计和实现。希望今天的分享能够帮助大家更好地理解 Spring 框架的原理和实现,也希望大家能够继续深入学习和研究 Java 技术,不断提升自己的能力。谢谢大家的阅读!
如有疑问或者更多的技术分享,欢迎关注我的微信公众号“知其然亦知其所以然”!
关键词:
大家好,我是小米,今天我们来聊聊Spring框架中的一个重要话题:循环依赖。在开发中,我们可能会遇到这样的2023-05-01
5月1日消息,对《塞尔达传说》的粉丝来说,5月是一个期待了很久的月份,因为多次跳票的任天堂新作《塞尔达2023-05-01
4月29日,我国东北地区“十四五”时期的重大清洁能源工程,辽宁省陆上单体容量最大的国家电投集团东北公司2023-05-01
一、天麻当归养生排骨汤食材天麻2根、芡实40克、莲子20克、黄芪10克、当归10克、去核红枣6颗、排骨1根、生2023-05-01
据@青岛气象消息,青岛市气象台1日06时发布:【青岛市区】今天白天,晴到少云,南风3到4级转4到5级阵风6级2023-05-01
一起为你科普解读2023-05-01
1、贝佳斯粉泥是一款具有清洁作用的泥膜,作为一款意大利的品牌,泥状面膜是它们家的一个主打品牌,清洁能2023-05-01
2022年,半导体正处于下行周期,部分公司的经营业绩也出现下滑。但在晶圆厂资本开支周期下,行业呈现结构性2023-05-01
1、成都双流机场到九寨沟九黄机场,飞行时间40分钟,价格在900-1200元之间。2、(单程)到了九黄机场不要以2023-05-01
北京时间4月30日3点30分,NBA季后赛继续进行,金州勇士前往客场挑战萨克拉门托国王。本场比赛的胜者将直接2023-05-01
1、《宋诗与宋代商业》是2006年河北教育出版社出版的图书,作者是张金花。2、本书试图通过“以诗证史”对宋2023-05-01
1、隼读音:sǔn,声母是s,韵母是un,声调是三声。2、隼部首:隹部,部外笔画:2画,总笔画:10画3、释义2023-05-01
1、看配料表。现实生活中,人们没有条件直接去蜂蜜厂里买蜂蜜,都是在超市中或者蜂蜜店铺当中买蜂蜜。在挑2023-04-30
五一假期想要出行,很多人会选择搭乘列车。而在进站安检时,不少旅客因携带违禁物品被查,因此耽误了旅途。2023-04-30
文 羊城晚报全媒体记者张豪通讯员李显陈文海岳振华4月28日中午12时,珠海出入境边防检查总站湛江边防检查站2023-04-30
00:47这个“五一”假期,济南公安“意外”火了。打开朋友圈、视频号、抖音,哪哪都有举着喇叭在景区喊话的2023-04-30
在对阵热刺的比赛前,红军后卫范迪克在接受《利物浦回声报》采访时表示,这将是另一个巨大的挑战。范迪克这2023-04-30
据新华社悉尼4月30日电据澳大利亚媒体4月30日报道,一名男孩日前在西澳大利亚州一处海滩浮潜时被鲨鱼咬伤,2023-04-30
随着房地产行业从高速增长进入平稳发展阶段,房企之间的竞争也不再唯“规模”论,而是走向“高质量”时代。2023-04-30
饸饹面在北方十分受欢迎,夏天吃凉拌,冬天吃浇汤。过去的人都用豆面、荞麦面、玉米面等制作。为了让大家在2023-04-30
当然,无论接下来对手是国王还是勇士,湖人也谈不上实力占据优势,至少外线攻击点比较密集的球队,湖人这种2023-04-30
出师表原文带拼音标准版视频,出师表原文带拼音这个很多人还不知道,现在让我们一起来看看吧!1、先帝创业未2023-04-30
一、题文二、解答本文到此结束,希望对大家有所帮助。2023-04-30
“五一”旅游风向标,怎么能少了世界的“敦煌”。火爆之下,抽丝剥茧,看到的是城市高效的治理效能,是满满2023-04-30
欢迎观看本篇文章,小升来为大家解答以上问题。广东十年爱情故事歌词,无疑是很有心的歌词很多人还不知道,2023-04-30
