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

成都家具企业网站建设营销顾问

成都家具企业网站建设,营销顾问,杭州网站建设优化,云校招企业服务平台🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring 中的三级缓存机制详解一、三级缓存定…

🤟致敬读者

  • 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉

📘博主相关

  • 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息

文章目录

    • Spring 中的三级缓存机制详解
      • 一、三级缓存定义(在 `DefaultSingletonBeanRegistry` 中)
      • 二、解决循环依赖的核心流程(以 A→B→A 为例)
        • 1. 创建 Bean A
        • 2. 创建 Bean B
        • 3. 完成 Bean A
      • 三、关键源码解析
        • 1. 从缓存获取 Bean 的优先级 (`getSingleton()`)
        • 2. 曝光早期引用 (`addSingletonFactory()`)
      • 四、三级缓存的本质作用
      • 五、高频面试问题详解
        • 1. 为什么需要三级缓存?二级不行吗?
        • 2. 哪些场景无法解决循环依赖?
        • 3. 如何证明三级缓存的存在?
      • 六、典型循环依赖解决方案对比
      • 七、面试实战回答模板


📃文章前言

  • 🔷文章均为学习工作中整理的笔记。
  • 🔶如有错误请指正,共同学习进步。

Spring 中的三级缓存机制详解

在这里插入图片描述

Spring 的三级缓存机制是解决循环依赖问题的核心设计,也是面试中高频考点。下面从原理、流程、源码三个维度深入解析:


一、三级缓存定义(在 DefaultSingletonBeanRegistry 中)

// 1. 一级缓存:存放完全初始化好的Bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);// 2. 二级缓存:存放早期曝光对象(已实例化但未初始化)
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);// 3. 三级缓存:存放单例工厂(用于生成代理对象)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

二、解决循环依赖的核心流程(以 A→B→A 为例)

1. 创建 Bean A
实例化A
将A的ObjectFactory放入三级缓存
填充A的属性 - 发现依赖B
2. 创建 Bean B
graph TDB1[实例化B] --> B2[将B的ObjectFactory放入三级缓存]B2 --> B3[填充B的属性 - 发现依赖A]B3 --> B4[从三级缓存获取A的ObjectFactory]B4 --> B5[调用getObject()获取A的早期引用]B5 --> B6[将A从三级缓存升级到二级缓存]
3. 完成 Bean A
B创建完成
将B注入A
执行A的初始化方法
将A放入一级缓存
清除二级缓存

三、关键源码解析

1. 从缓存获取 Bean 的优先级 (getSingleton())
protected Object getSingleton(String beanName, boolean allowEarlyReference) {// 1. 从一级缓存查询Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {// 2. 从二级缓存查询singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {// 3. 从三级缓存获取ObjectFactoryObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {// 创建早期引用(可能生成代理对象)singletonObject = singletonFactory.getObject();// 升级到二级缓存this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;
}
2. 曝光早期引用 (addSingletonFactory())
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {// 将ObjectFactory放入三级缓存this.singletonFactories.put(beanName, singletonFactory);// 清除二级缓存中的旧数据this.earlySingletonObjects.remove(beanName);}}
}

四、三级缓存的本质作用

缓存级别存储内容核心作用
一级缓存完全初始化好的 Bean提供最终可用对象
二级缓存早期曝光对象(未初始化)避免重复创建代理对象
三级缓存ObjectFactory分离实例化与初始化,支持AOP

五、高频面试问题详解

1. 为什么需要三级缓存?二级不行吗?
  • 关键原因:处理 AOP 代理对象的循环依赖
  • 二级缓存缺陷
    // 若只有二级缓存:
    A 实例化 → 放入二级缓存 → 填充属性依赖 B
    B 实例化 → 从二级缓存拿到原始对象 A(非代理)→ 完成初始化
    A 继续初始化 → 生成代理对象 → 导致 B 持有的是原始对象(非代理)
    
  • 三级缓存解决方案
    通过 ObjectFactory.getObject() 动态决定返回原始对象还是代理对象
2. 哪些场景无法解决循环依赖?
场景原因
构造器注入实例化前就需要完整依赖,无法提前曝光对象
原型(prototype)Spring 不缓存原型 Bean
@Async 注解代理对象在初始化后生成,无法通过 ObjectFactory 提前创建
自定义初始化某些 InitializingBean 实现可能依赖完整状态
3. 如何证明三级缓存的存在?

通过调试查看容器状态:

// 查看缓存内容
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
Field singletonObjects = beanFactory.getClass().getDeclaredField("singletonObjects");
singletonObjects.setAccessible(true);
Map<String, Object> cache = (Map) singletonObjects.get(beanFactory);
System.out.println("一级缓存: " + cache.keySet());

六、典型循环依赖解决方案对比

方案优点缺点
三级缓存Spring原生支持,自动处理无法解决构造器注入
Setter注入兼容三级缓存机制代码侵入性强
@Lazy注解延迟加载打破循环可能引发NPE问题
重构代码彻底解决设计问题业务改造成本高

七、面试实战回答模板

面试官:请解释Spring如何解决循环依赖?

回答

Spring 通过三级缓存机制解决单例Bean的循环依赖问题:

  1. 当Bean实例化后,会将其ObjectFactory存入三级缓存
  2. 依赖注入时若发现循环依赖,通过ObjectFactory.getObject()获取早期引用
  3. 获取到的对象会升级到二级缓存
  4. Bean完全初始化后放入一级缓存

关键点在于:

  • 三级缓存的ObjectFactory支持AOP代理的动态生成
  • 避免了构造器注入和原型Bean的循环依赖
  • 通过缓存分离实例化和初始化过程

源码体现在DefaultSingletonBeanRegistry的getSingleton()方法中…

掌握三级缓存机制需要深入理解Spring生命周期,建议结合源码调试加深理解(关键类:AbstractAutowireCapableBeanFactoryDefaultSingletonBeanRegistry)。


📜文末寄语

  • 🟠关注我,获取更多内容。
  • 🟡技术动态、实战教程、问题解决方案等内容持续更新中。
  • 🟢《全栈知识库》技术交流和分享社区,集结全栈各领域开发者,期待你的加入。
  • 🔵​加入开发者的《专属社群》,分享交流,技术之路不再孤独,一起变强。
  • 🟣点击下方名片获取更多内容🍭🍭🍭👇

http://www.dtcms.com/wzjs/320860.html

相关文章:

  • 兰州网站设计哪个平台好网络营销的有哪些特点
  • 做智能网站系统下载地址2024年阳性最新症状
  • 河北省建设机械协会是真的网站吗购买模板建站
  • 国外房屋设计网站长沙网络推广网站制作
  • 北京做网站网络公司b站怎么推广
  • 阿里巴巴网站更新怎么做佛山网络排名优化
  • 福州网站开发风格seo优化员
  • 关于网站制作报价个人网站模板建站
  • 掘金网站建设企业文化理念
  • 杭州品牌网站建设合肥网站排名提升
  • 酒类公司网站模板保定seo推广外包
  • 做led开关电源上什么网站好营销型网站优化
  • 苏州建网站哪家百度云登录入口
  • linux搭建个人网站域名停靠
  • 安徽网站建设 网新大数据培训包就业靠谱吗
  • 做个网站要钱吗搜索引擎优化内容包括哪些方面
  • 天津哪里能做网站高权重友情链接
  • 网站开发工具有哪些线上广告推广
  • 个人网站做企业备案吗百度seo关键词优化排行
  • 宁波易通宁波网站建设网络营销包括几个部分
  • dedecms产品展示织梦模板(营销型网站)广州seo
  • 接项目做的网站网站外链平台
  • vs2017html5网站开发百度网站入口链接
  • 自动优化网站建设今日国内新闻最新消息大事
  • 淘宝做代销在哪个网站上进货比较好关键词排名快速提升
  • 网站结构是什么陕西优化疫情防控措施
  • 让自己的电脑做网站的服务器优化二十条
  • 网上商城建站服务商看b站二十四小时直播间
  • 云浮网站网站建设搜索引擎推广的费用
  • 用于网站建设的费用怎么备注个人友情链接推广