首页 > 编程语言 >【编程底层原理】彻底搞懂Spring是如何利用三级缓存来解决循环依赖问题的(一级缓存为啥解决不了,二级缓存可以解决为啥也不合适,三级缓存为啥合适)

【编程底层原理】彻底搞懂Spring是如何利用三级缓存来解决循环依赖问题的(一级缓存为啥解决不了,二级缓存可以解决为啥也不合适,三级缓存为啥合适)

时间:2024-09-22 12:23:44浏览次数:11  
标签:缓存 对象 为啥 二级缓存 bean 创建 三级

一、整体推导思路

为了彻底搞懂Spring是如何利用三级缓存来解决循环依赖问题的,要么去找三级缓存的设计者了解其设计的初衷,要么利用反推法来进行倒推(即一级缓存为啥不行,二级缓存为啥也不合适)。
为了让大家能有一个更清晰的理解脉路,下面将先从反推法来介绍下一级缓存为啥不行、二级缓存为啥也不合适,然后再介绍为啥三级缓存适合解决循环依赖的问题,通过前后对比,理解起来也会更加清晰明了。

二、缓存的四个基本问题

另外,讲到缓存,都必定涉及到以下四个基本问题:

问题1:为啥要用缓存,即缓存的作用?

回答:为了加速不同使用者对共享资源的访问。通过把不需要多次创建的共享资源(如数据库连接、日志记录对象等),在其首次被创建后,按照key(资源名称)-value(资源实体)的方式缓存起来,以便下次能快速根据key来检索到该资源,而非再次创建。

问题2:何时进行缓存?

回答:当该对象是业务上需要缓存的共享资源,且首次被创建出来后,即可进行缓存

问题3:缓存的内容是啥?

回答:缓存的内容是资源实体对象。

问题4:缓存啥时候失效?

回答:当该资源实体对象在系统中没有存在的必要了;或者构成资源实体的基本信息有变化,需要根据变化后的基本信息来重新构建时,旧的缓存就失效了。
在Spring循环依赖这个讨论背景下,共享资源就是Spring容器管理的bean对象。

三、一级缓存为啥解决不了循环依赖的问题(缓存完整的bean对象)

如果设计成一级缓存,若存在循环依赖时,两个bean对象相互依赖,都需要拿到对方的bean对象,才能进行自身bean对象的创建,这时仅通过一级缓存的设计方案(完整的bean对象),两个bean对象的创建动作将永远无法结束,就像死锁一样无限期的死等下去。
而且,每个bean对象在创建完成后,无论后续是否被会被其他bean对象引用,都会无脑存放到一级缓存中,随着bean对象的不断增加,缓存的内容越来越多,势必对系统资源造成越来越大的压力。

四、二级缓存可以解决为啥也不合适(缓存尚未进行属性注入的早期bean对象)

如果设计成二级缓存,若存在循环依赖,两个bean对象相互依赖,因为有二级缓存的存在,不需要再等到构建出完整的bean对象,而是可以提前获取到尚未进行属性注入的早期的bean对象,这时两个bean对象的创建动作将不会因为获取不到对方的bean对象就无限期死等下去,而是可以正常进行下去。
注意:二级缓存是可以解决Spring的循环依赖问题,但是还存在资源消耗的问题以及当涉及代理对象时对象创建和对象缓存的职责耦合的复杂度问题。
但是,同一级缓存一样,在构造出的尚未进行属性注入的早期bean对象后,无论后续是否被会被其他bean对象引用,都会无脑存放到二级缓存中,随着bean对象的不断增加,缓存的内容越来越多,势必也会对系统资源造成越来越大的压力。
而且,因为有可能涉及到代理对象的逻辑,所以如果只设计成二级缓存,那么代理对象的创建和对象缓存这两个职责势必会耦合在一块,代理逻辑复杂度也会上升。

五、三级缓存为啥合适(缓存构建bean的工厂对象)

如果设计成三级缓存,若存在循环依赖,两个bean对象相互依赖,因为有二级缓存的存在,不需要再等到构建出完整的bean对象,而是可以提前获取到尚未进行属性注入的早期的bean对象,这时两个bean对象的创建动作将不会因为获取不到对方的bean对象就无限期死等下去,而是可以正常进行下去。
而且,因为有三级缓存的存在,只有在其他bean对象需要该bean对象的时候,才会到三级缓存获取bean工厂开始bean对象的缓存(此时可以进行代理对象的处理,如果是代理对象则创建代理对象并放到二级缓存,否则通过反射获取原始对象放到二级缓存,并清除三级缓存),而非在bean对象创建后就无脑的进行缓存。即只有在真正需要读取缓存内容的时候才进行缓存,即将缓存的动作延迟到了需要读取缓存的时候。这样,就极大了减少了因为缓存给系统资源带来的压力。
并且,因为有三级缓存的存在,还可以将代理对象的创建和对象缓存的职责解耦,代理逻辑也更加清晰明了。

六、三级缓存的整体流程

在bean对象创建时,会将bean的工厂对象缓存到三级缓存里,当有其他bean对象首次需要引用该bean对象时,会首先检查一级缓存是否存在完整的bean对象,若有则获取并返回;否则检查二级缓存是否存在尚未进行属性注入的早期bean对象,若有则获取并返回;否则检查三级缓存是否存在bean的工厂对象,若有则判断如果是代理对象则创建代理对象并放到二级缓存,否则通过反射获取原始对象放到二级缓存,并清除三级缓存。

存在 不存在 存在 不存在 存在 开始 创建Bean对象 缓存工厂对象到三级缓存 其他Bean引用该Bean 一级缓存检查 获取并返回完整Bean对象 二级缓存检查 获取并返回早期Bean对象 三级缓存检查 是否代理对象 创建代理对象 放入二级缓存 通过反射获取原始对象 放入二级缓存 清除三级缓存 结束

这个流程图描述了Bean对象创建和引用时的缓存检查过程。当一个Bean对象被创建时,它的工厂对象会被缓存到三级缓存中。当其他Bean对象需要引用这个Bean时,会按照一级缓存、二级缓存和三级缓存的顺序进行检查,并根据情况获取Bean对象或创建代理对象。

七、总结

一级缓存(缓存完整的bean对象),无法解决循环依赖问题,而且存在资源浪费;
二级缓存(缓存尚未进行属性注入的早期bean对象),可以解决循环依赖问题,但是存在资源浪费,而且存在当涉及代理对象时对象创建和对象缓存的职责耦合的复杂度问题;
三级缓存(缓存构建bean的工厂对象),不仅可以解决循环依赖问题,而且通过将缓存的动作延迟到了需要读取缓存的时候,极大减少了因缓存给系统资源带来的压力。

标签:缓存,对象,为啥,二级缓存,bean,创建,三级
From: https://blog.csdn.net/u010425839/article/details/142432809

相关文章

  • 商城项目改进分布式缓存下的登录逻辑和页面展示-----商城项目
    packagecom.alatus.mall.auth.app;importcom.alatus.common.constant.AuthServerConstant;importcom.alatus.common.exception.BizCodeEnum;importcom.alatus.common.utils.R;importcom.alatus.common.vo.MemberRespVo;importcom.alatus.mall.auth.feign.MemberFe......
  • 项目实战:一步步实现高效缓存与数据库的数据一致性方案
    Hello,大家好!我是积极活泼、爱分享技术的小米!今天我们来聊一聊在做个人项目时,如何保证数据一致性。数据一致性问题,尤其是涉及缓存与数据库的场景,可以说是我们日常开发中经常遇到的挑战之一。今天我将以一个简单的场景为例,带大家一步步了解如何解决这个问题——既能高效利用缓存,又能......
  • 【信号传输】DMA传输只能收到一半数据,发送123456 只能收到 123, 发送abcd只能收到ab,缓
    系列文章目录1.元件基础2.电路设计3.PCB设计4.元件焊接5.板子调试6.程序设计7.算法学习8.编写exe9.检测标准10.项目举例11.职业规划文章目录方案一、改DMA中断方案二、改数据类型方案三、改数据长度后记方案一、改DMA中断每个DMA通道都可以在DMA传......
  • Redis典型应用 - 缓存
    1.什么是缓存?简单来说,核心思路就是把一些常用的数据放到触手可及(访问速度更快)的地方,方便随时读取。对于计算机硬件来说,往往访问速度越快的设备,成本越高,存储空间越小。缓存是更快,但是空间上往往是不足的。因此大部分的时候,缓存只放一些热点数据(访问频繁的数据),就非常有用了。......
  • Android RecyclerView 缓存机制深度解析与面试题
    本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点引言RecyclerView是Android开发中用于展示列表和网格的强大组件。它通过高效的缓存机制,优化了滑动性能和内存使用。本文将深入探讨RecyclerView的缓存机制,并......
  • 为啥chrome查看到网页,只有5000多行,应该有1万多行才对
    大家好,我是皮皮。一、前言前几天在Python白银交流群【磐奚鸟】问了一个Python网络爬虫处理的问题,这里拿出来给大家分享下。二、实现过程这里【惜君】给了一个指导,可能网站有限制数据量。这里【瑜亮老师】发现了问题所在,如下图所示:数据方面确实存在,顺利地解决了粉丝的问题。三、总结......
  • 为啥chrome查看到网页,只有5000多行,应该有1万多行才对
    大家好,我是皮皮。一、前言前几天在Python白银交流群【磐奚鸟】问了一个Python网络爬虫处理的问题,这里拿出来给大家分享下。二、实现过程这里【惜君】给了一个指导,可能网站有限制数据量。这里【瑜亮老师】发现了问题所在,如下图所示:数据方面确实存在,顺利地解决了粉丝的问......
  • 我有了个新同桌,但是他的朋友圈总是想传递一些东西。 我却看不惯,为啥看不惯我也不知道
    反正就是这样。 我准备把他屏蔽了,也不跟他争辩什么。 https://zhuanlan.zhihu.com/p/452630979曹大的傻逼定律。第一定律,从来没觉得自己傻逼过的,往往是不可救药的大傻逼。第二定律,觉得别人都是傻逼的,往往自己才是最傻逼的一个。第三定律,收割傻逼的会被傻逼们封神,试图唤醒......
  • Redis面试题-如何保持缓存一致性
    1、延迟双删延迟双删策略是一种用于解决缓存与数据库之间数据一致性问题的方法。其基本思想是在更新数据库时,通过两次删除缓存的操作来尽可能地保证数据的一致性。具体步骤包括:首先,在更新数据库之前删除缓存;然后,执行数据库更新操作;最后,在延迟一段时间后再次删除缓存。优点:减......
  • 短视频全套源码,解决缓存击穿的常用方案
    短视频全套源码,解决缓存击穿的常用方案一、设置合理的过期时间固定过期时间:为短视频全套源码中的热点数据设置一个合理的固定过期时间,可以有效地减少数据库的访问频率,但不能完全避免缓存击穿问题。随机过期时间:通过为短视频全套源码中的缓存设置不同的随机过期时间,可以使缓......