当前位置: 首页 > article >正文

Spring中三级缓存详细讲解

1、Spring三级缓存是什么,过程是怎么样的?

Spring 中的三级缓存主要用于单例 Bean 的生命周期管理,特别是在循环依赖时,它通过不同阶段暴露 Bean 实例来确保依赖注入的顺利完成。缓存的内容如下:

  1. 一级缓存 (singletonObjects)存储完全初始化的单例 Bean。该缓存中存储的是已经完成初始化的 Bean 对象,包括所有的属性注入和生命周期回调方法(如 @PostConstruct)都已完成。

  2. 二级缓存 (earlySingletonObjects)存储实例化但尚未完成所有初始化步骤的 Bean 引用。也就是 Bean 已经完成了实例化,并完成了依赖注入(如字段注入),但可能还没有执行初始化方法(如 @PostConstruct)。二级缓存用于解决循环依赖问题,当需要注入的 Bean 还没有完全初始化时,可以先返回该 Bean 的早期引用。

  3. 三级缓存 (singletonFactories)存储的是创建 Bean 的工厂(ObjectFactory),而不是直接存储 Bean 实例。这些工厂延迟返回真正的 Bean 实例,直到它们完成初始化。三级缓存用于处理 循环依赖 的核心,当一个 Bean 处于创建过程中,另一个 Bean 依赖它时,可以从三级缓存中获取一个工厂对象,该工厂会在 Bean 完全初始化后,生成一个完整的 Bean 实例。

2、从缓存中获取单例对象

2.1、代码解读

public Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 1. 检查一级缓存,获取已完成初始化的 Bean
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null && this.singletonsCurrentlyInCreation.contains(beanName)) {
        // 2. 如果一级缓存没有,且 Bean 正在创建中,则检查二级缓存
        singletonObject = this.earlySingletonObjects.get(beanName);
        if (singletonObject == null && allowEarlyReference) {
            // 3. 如果二级缓存也没有,允许提前引用时,检查三级缓存
            ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
            if (singletonFactory != null) {
                // 4. 从三级缓存中获取 Bean 实例
                singletonObject = singletonFactory.getObject();
                // 5. 将生成的对象放入二级缓存
                this.earlySingletonObjects.put(beanName, singletonObject);
                // 6. 从三级缓存中移除工厂
                this.singletonFactories.remove(beanName);
            }
        }
    }
    // 7. 返回从缓存中获取的单例对象
    return singletonObject;
}

2.2、执行流程

  1. 一级缓存 (singletonObjects):
    检查一级缓存,获取完全初始化的 Bean。
    如果一级缓存中存在该对象,则直接返回。

  2. 二级缓存 (earlySingletonObjects):
    如果一级缓存中没有找到该对象,且该对象正在创建过程中(this.singletonsCurrentlyInCreation),则检查二级缓存。
    如果二级缓存中存在早期暴露的 Bean,则直接返回。

  3. 三级缓存 (singletonFactories):
    如果二级缓存中也没有,并且允许提前引用(allowEarlyReference 为 true),则从三级缓存中获取工厂对象(ObjectFactory)。
    调用 ObjectFactory.getObject() 方法生成 Bean 实例。
    将生成的实例放入二级缓存,同时从三级缓存中移除对应的工厂。


http://www.kler.cn/a/501092.html

相关文章:

  • 在 Linux 下Ubuntu创建同权限用户
  • Windows安装ES单机版设置密码
  • HTML5实现好看的博客网站、通用大作业网页模板源码
  • AllData是怎么样的一款数据中台产品?
  • LeetCode:108.将有序数组转换为二叉搜索树
  • 【深度学习】多目标融合算法(二):底部共享多任务模型(Shared-Bottom Multi-task Model)
  • Pytest-Bdd-Playwright 系列教程(完结篇):本框架的功能参数说明
  • JavaScript 数组及其常用方法
  • 《解锁鸿蒙Next系统人工智能语音助手开发的关键步骤》
  • 初学spring 框架(了解spring框架的技术背景,核心体现,入门案例)
  • Oracle 表分区简介
  • ASP.NET CORE 实现微服务 - 分布式事务 - 2PC、3PC、TCC
  • eno4j 基础 CQL 学习
  • C++类的引入
  • C#对象池
  • 网络安全 | 什么是Bot防护?
  • SOLID原则学习,里氏替换原则
  • 计算机网络之---RIP协议
  • 51 单片机和 STM32 引脚命名对照表与解析
  • 论文笔记(四十七)Diffusion policy: Visuomotor policy learning via action diffusion(下)
  • 企业全文搜索-搜索权限,非侵入文档同步,权限同步 ,扩展字段
  • 什么是大数据?
  • VUE3 组件的使用
  • Linux新手入门手册
  • mysql本地安装和pycharm链接数据库操作
  • mybatis分页插件:PageHelper、mybatis-plus-jsqlparser(解决SQL_SERVER2005连接分页查询OFFSET问题)