首页 > 其他分享 >【Spring】Spring三级缓存以及如何解决循环依赖

【Spring】Spring三级缓存以及如何解决循环依赖

时间:2024-12-14 16:27:28浏览次数:7  
标签:初始化 缓存 Spring 二级缓存 Bean 实例 三级

1.Spring三级缓存

Spring 的三级缓存机制主要应用于其依赖注入(DI)容器中,特别是在单例(Singleton)作用域的 Bean 创建过程中。这三级缓存的设计目的是为了提高性能,减少重复创建 Bean 的开销,并确保 Bean 的唯一性和一致性。


1.1 一级缓存(Singleton Objects Cache)

存储位置:singletonObjects,这是一个 ConcurrentHashMap,用于存储已经完全初始化的单例 Bean。
作用:当一个 Bean 完全初始化并准备好使用时,它会被放入 singletonObjects 中。下次请求同一个 Bean 时,直接从这个缓存中获取,无需重新创建。
特点:存储的是完全初始化的 Bean 实例。

1.2 二级缓存(Early Singleton Objects Cache)

存储位置:earlySingletonObjects,这也是一个 ConcurrentHashMap,用于存储尚未完全初始化的单例 Bean。
作用:在 Bean 的初始化过程中,如果其他 Bean 依赖于当前正在初始化的 Bean,可以从 earlySingletonObjects 中获取一个早期的引用。这样可以解决循环依赖的问题。
特点:存储的是未完全初始化的 Bean 实例。

1.3 三级缓存(Singleton Factories Cache)

存储位置:singletonFactories,同样是一个 ConcurrentHashMap,用于存储 Bean 工厂对象。
作用:在 Bean 初始化过程中,如果其他 Bean 依赖于当前正在初始化的 Bean,可以从 singletonFactories 中获取一个工厂对象,通过工厂对象创建一个早期的 Bean 实例。
特点:存储的是 Bean 工厂对象,用于创建早期的 Bean 实例。


2.三级缓存的工作机制

2.1 检查一级缓存

当请求一个单例 Bean 时,首先检查一级缓存(singletonObjects)。
如果找到,直接返回该 Bean 实例。

2.2 检查二级缓存

如果一级缓存(singletonObjects)中没有找到,检查二级缓存(earlySingletonObjects)。
如果找到,返回该 Bean 实例(未完全初始化的早期引用)。

2.3 检查三级缓存

如果二级缓存(earlySingletonObjects) 中也没有找到,检查三级缓存(singletonFactories)。这是存放 Bean 工厂方法的地方。当容器开始创建 Bean 时,三级缓存存储了生成 Bean 的工厂方法。如果在三级缓存中找到,则使用工厂对象创建一个早期的 Bean 实例,并将其放入二级缓存( earlySingletonObjects ),然后返回该早期引用。

2.4 创建并初始化 Bean

如果以上缓存中也没有找到,开始创建并初始化 Bean。Spring 将创建 Bean。这个过程中,Bean 会被放入三级缓存,并调用 populateBean 方法注入依赖,最后将完成初始化的 Bean 放入一级缓存中。在初始化过程中,如果其他 Bean 依赖于当前正在初始化的 Bean,可以通过二级缓存(earlySingletonObjects)或三级缓存(singletonFactories) 获取早期引用。

初始化完成后,将 Bean 实例放入一级缓存(singletonObjects)中,并从二级缓存(earlySingletonObjects) 和三级缓存(singletonFactories)缓存中移除相关的条目。


3.循环依赖

循环依赖(Circular Dependency)是指两个或多个对象相互依赖,导致它们无法被正常创建。最常见的场景是两个类互相引用对方,构成了一个闭环。

例如,假设有两个类 A 和 B:

@Component
public class A {
    private B b;
    
    @Autowired
    public A(B b) {
        this.b = b;
    }
}

@Component
public class B {
    private A a;
    
    @Autowired
    public B(A a) {
        this.a = a;
    }
}

在上面的代码中,A 类依赖于 B 类,B 类又依赖于 A 类,这种循环依赖关系会导致Spring容器无法解决对象的创建。

Spring默认不允许有循环依赖存在,因为这会造成无限的递归调用,进而导致堆栈溢出错误。


4.三级缓存如何解决循环依赖

假设我们有两个 Bean:A 和 B,它们之间存在循环依赖关系,即 A 依赖 B,B 依赖 A。

4.1 请求 Bean A

  • Spring 容器接收到请求,开始创建 Bean A。
  • 检查一级缓存,如果没有找到 Bean A,继续检查二级缓存三级缓存
  • 如果都没有找到,开始实例化 Bean A,并将 Bean A 的工厂对象放入三级缓存中。

4.2 初始化 Bean A

  • 在初始化 Bean A 的过程中,发现 Bean A 依赖于 Bean B。
  • 请求 Bean B,开始创建 Bean B。
  • 检查一级缓存,如果没有找到 Bean B,继续检查二级缓存三级缓存
  • 如果都没有找到,开始实例化 Bean B,并将 Bean B 的工厂对象放入三级缓存中。

4.2 初始化 Bean B

  • 在初始化 Bean B 的过程中,发现 Bean B 依赖于 Bean A。
  • 请求 Bean A,此时 Bean A 还没有完全初始化,但是已经在三级缓存中。
  • 三级缓存中获取 Bean A 的工厂对象,创建一个早期的 Bean A 实例,并将这个早期实例放入二级缓存中。
  • 将这个早期的 Bean A 实例注入到 Bean B 中,继续初始化 Bean B。

4.2 完成 Bean B 的初始化

  • Bean B 完成初始化后,将 Bean B 放入一级缓存中,并从二级缓存三级缓存中移除相关的条目。

4.2 完成 Bean A 的初始化

  • 回到 Bean A 的初始化过程,继续初始化 Bean A。
  • 完成 Bean A 的初始化后,将 Bean A 放入一级缓存中,并从二级缓存三级缓存中移除相关的条目。
    在这里插入图片描述

标签:初始化,缓存,Spring,二级缓存,Bean,实例,三级
From: https://blog.csdn.net/weixin_50591390/article/details/144153884

相关文章

  • springboot基于知识图谱与学习行为分析的在线学习平台开发
    目录功能和项目介绍系统实现截图开发核心技术介绍操作手册核心代码部分展示视频演示/源码获取功能和项目介绍jdk版本:jdk1.8+编程语言:java框架支持:springboot/ssm数据库:mysql版本不限数据库工具:Navicat/SQLyog都可以前端:vue.js+ElementUI开发工具:IDEA或......
  • springboot基于微信小程序的家政服务员预约管理系统
    收藏关注不迷路!!......
  • 基于springboot 商户点评管理系统(源码+LW+部署讲解+数据库)
    !!!!!!!!!很多人不知道选题怎么选不清楚自己适合做哪块内容都可以免费来问我避免后期給自己答辩找麻烦增加难度(部分学校只有一次答辩机会没弄好就延迟毕业了)源码获取:https://pan.baidu.com/s/1aRpOv3f2sdtVYOogQjb8jg?pwd=jf1d提取码:jf1d !!!!!!!!!项目介绍随着信息技术的发展和数......
  • spring-boot-devtools 实现热部署
    1.devtoolsspring为开发者提供了一个名为spring-boot-devtools的模块来使SpringBoot应用支持热部署,提高开发者的开发效率,无需手动重启SpringBoot应用。2.项目搭建本文是采用IDEA搭建的SpringBoot应用,通过spring-boot-devtools配置,可以支持修改java文件会自动重启程......
  • springboot美容院会员管理系统-毕业设计源码28455
    目录摘要1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2系统分析2.1可行性分析2.2系统流程分析2.2.1系统开发流程2.2.2用户登录流程2.2.3系统操作流程2.2.4添加信息流程2.2.5修改信息流程2.2.6删除信息流程2.3 系统......
  • springboot二手动漫周边交易网站-毕业设计源码16260
    目 录摘要1绪论1.1选题背景1.2研究意义1.3论文结构与章节安排2 二手动漫周边交易网站系统分析2.1可行性分析2.2系统流程分析2.2.1数据流程3.3.2业务流程2.3系统功能分析2.3.1功能性分析2.3.2非功能性分析2.4系统用例分析2.5本章小......
  • 语义缓存:提升 RAG 性能的关键策略
    检索增强生成(Retrieval-AugmentedGeneration,简称RAG)(RAG综述:探索检索增强生成技术的多样性与代码实践)技术已经成为构建高性能AI模型的重要基石。RAG通过结合先进的语言模型与外部知识检索,能够生成既准确又富含上下文的响应。然而,尽管RAG功能强大,但它也伴随着一系列挑战,如高令牌......
  • 为什么需要清除浏览器缓存才能正常访问HTTP?
    301重定向是一种永久重定向,浏览器会将这种重定向信息缓存起来,以便下次访问相同URL时直接跳转到目标URL,而不需要再次请求服务器。因此,即使你在服务器端取消了301重定向规则,浏览器仍然会根据缓存的重定向信息直接跳转到HTTPS页面。为了确保能够正常访问HTTP页面,需要清除浏览器的缓存......
  • 基于SpringBoot+Vue的小学课外综合管理系统
    收藏关注不迷路!!......
  • 【开源免费】基于Vue和SpringBoot的课程管理平台(附论文)
    本文项目编号T006,文末自助获取源码\color{red}{T006,文末自助获取源码}......