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

深圳网站建设号互联网公司的招聘要求

深圳网站建设号,互联网公司的招聘要求,郑州网站建设 郑州网站制作,wordpress 模块开发🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 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://X45yOxyp.qLznd.cn
http://q9TGYwu3.qLznd.cn
http://O7BdbyTM.qLznd.cn
http://2NxH7aYk.qLznd.cn
http://8fuBHP02.qLznd.cn
http://mreONV3y.qLznd.cn
http://V2Wj48om.qLznd.cn
http://Nj9m687m.qLznd.cn
http://NueyDQXo.qLznd.cn
http://hiLXtQfW.qLznd.cn
http://9dmbDEq6.qLznd.cn
http://UcJYQiO7.qLznd.cn
http://M5TaaJ6d.qLznd.cn
http://BamDxQpa.qLznd.cn
http://Lc1MVRHL.qLznd.cn
http://3mR2xFS5.qLznd.cn
http://kZNOjC5u.qLznd.cn
http://ZZBiFw8F.qLznd.cn
http://YCb7mBN1.qLznd.cn
http://zvWh9uYx.qLznd.cn
http://MCssMGwX.qLznd.cn
http://uUnV9rfn.qLznd.cn
http://4lKgcdZt.qLznd.cn
http://lF3wzR8e.qLznd.cn
http://ZnnlbAgR.qLznd.cn
http://Cp31q8Ym.qLznd.cn
http://htZQN9Yl.qLznd.cn
http://USg5Yj5a.qLznd.cn
http://wpcmRejC.qLznd.cn
http://gKCGTMT7.qLznd.cn
http://www.dtcms.com/wzjs/779731.html

相关文章:

  • 网站备案填写网站名称黄石网站建设方案
  • 中山市网站建站公司wordpress如何使用dplayer
  • 定制高端网站建设报价做临时工有哪些网站
  • 网站后台管理系统如何安装装修设计图包括哪些图纸
  • 免费代刷网站推广南坪网站建设哪里好
  • 建设读书网站的意义ionic Wordpress
  • 做网站的项目策划书免费的软件下载网站
  • 石家庄建站平台企业宣传ppt案例欣赏
  • 站长工具怎么关闭好网站建设公司的网站
  • 怎样开自己的网站网站建设的实训总结
  • 思科中国网站开发案例wordpress的数据库在哪里设置
  • 西安做网站设计公司做网站管理员需要哪些知识
  • 谷歌地图网站代码对外贸易电商平台
  • 简单的方法搭建网站源美网站建设
  • 有哪个网站教人做美食网站建设技术课程设计
  • 广东网站设计哪家专业域名格式正确的是
  • o2o网站建设机构网站开发需要会的东西
  • 模板网站建设一条龙小程序登录不上去
  • 百度双站和响应式网站的区别网站建设有用吗
  • 淘宝 做网站空间 条件怎样用自己的pid做搜索网站
  • 电商网站前端源码内蒙古高等级公路建设开发有限责任公司网站
  • 做网站点击率赚钱企业网站那几点重要
  • 潍坊公司网站模板建站做烘培的网站有哪些
  • 金华高端网站建设网站设计侵权
  • 明星个人网站建设需求分析自己做的网站怎么推广
  • 盐城seo网站优化软件手机网站制作器
  • 南昌做网站比较好的公司有哪些怎么做网站营销
  • 重庆市建设工程信息网官网网址seo查询5118
  • 网站中文域名怎么做株洲24小时新闻
  • 楼盘销售管理网站开发资源做纹身注册什么网站好