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

03.spring实现创建单例原理

引例

A 依赖 B,B 依赖 A 的循环依赖,通过 XML 配置依赖(A 的 setB 注入 B,B 的 setA 注入 A),初始化的时候,四大皆空

singletonObjects(一级);
earlySingletonObjects(二级);// key:beanName value:未完成依赖注入的bean
beansingletonFactories(三级); //key:beanName value:可以返回bean实例的函数,该实例未完成依赖注入
singletonCurrentlyInCreation(正在创建中标记) //bean 处于二、三级缓存中,均为创建中

代码调用链路:getBean ("a") → DefaultSingletonBeanRegistry#getSingleton ("a")

实现三级缓存原理

  • getSingleton ("a") 首次查询缓存,三缓存都未命中(即缓存未命中),则进入创建 A 的实例中,并注册三级缓存,进入 AbstractAutowireCapableBeanFactory#doCreateBean 方法,执行 A 的实例化和加入三级缓存,在该方法内会使用 beforeSingletonCreation (beanName) 标记 A 为创建中,此时:
    singletonFactories:{"a" : () -> getEarlyBeanReference("a",mbd,A@ram)} // 即 getEarlyBeanReference("a",mbd,A@ram),该函数返回早期的A实例
    singletonCurrentlyInCreation:{"a"}
    
  • A 实例化后注入 B,触发 B 的实例化,即 A 实例化后进入属性注入阶段(populateBean),解析到依赖 B,调用 getBean ("b") [和getBean("a")一样],又来到 B 的属性注入阶段,调用 getBean ("a"),在三级缓存中查询到了 A,调用 getObject () [即 getEarlyBeanReference("a",mbd,A@ram)], 生成 A 的早期实例,( A 不需要代理,直接返回 A@ram,若 A 需要代理,则返回 A@proxy),返出
    返回前,将 A 从三级缓存存至二级缓存(即 A@own 从三级缓存移到二级缓存后),并将
    三级缓存中的 A@ram 移除。
  • B 完成注入 A 后,即完成 B 的属性注入和初始化,调用 addSingleton ("b",b@ram) 存入一级缓存,同时移除二、三级缓存中 “b” 且移除 B 的正在创建标记。
    AfterSingletonCreation("b")
    
  • A 继续注入 B,从一级缓存中获取 B@own,之后与步骤 3 一样

                   三级缓存完结

课后小问题

1.在查找 a 的自身时候,有没有可能存在命中二、三级缓存?

boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReference && !isSingletonCurrentlyInCreation (beanName)
if (earlySingletonExposure) {// 3. 条件满足:注册三级缓存(核心操作)addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}
  • ① 无循环依赖时,查找 A 只会命中一级缓存 (创建后)。若第一次未命中,直接触发 A 的创建,直接加入一级缓存。
  • ② 有循环依赖时,B 依赖于 A, 步骤 2 访问 A 命中三级缓存。若还有 C 依赖于 A (即 A 同时 B、C 循环依赖) 此时访问 A 命中二级缓存。

核心总结:在 Spring 的设计中,当从二级或三级缓存中找到 Bean 实例时,会直接返回,这是安全的,因为:

1.实例引用唯一,后续初始化会完善状态,依赖方持有的引用本身指向完整的对象。
2.容器启动过程中,依赖方不会提前使用初始化后的实例,最终所有的 Bean 都会在容器初始化后进入可用状态。

关于标记:

1.在实例化前就要标记,标记是为了防止多个相同的 beanName 重复创建。
2.当有一个 beanName (如 A) 被标记后,再去标记相同的 beanName 便会发生异常。
3.只有三级缓存均未命中时,才会触发 doCreateBean 进行标记,实例化,加入三级缓存。

http://www.jsqmd.com/news/57905/

相关文章:

  • 2025口碑最好的十大留学中介机构香港
  • 2025佛山留学机构哪家好
  • 2025年12月旋转接头厂家权威推荐榜:高温/高压/高速/液压/导热油/蒸汽/水用旋转接头,匠心工艺与稳定性能的工业连接解决方案
  • 2025如何选择澳大利亚出国留学中介机构
  • 高效安全的文件自动同步系统,为企业数据传输提供可靠支撑
  • 2025青岛留学中介名单公布
  • CSharp 权限对照表 + 使用场景分析
  • 2025留学中介是否可靠
  • JSAPIThree 数据源系统学习笔记:让数据在地图上可视化
  • 2025口碑好的留学机构
  • 2025年口碑好的控制阀门厂家最新权威实力榜
  • 2025年成都十大移民机构排行榜:四川诺华移民机构靠谱吗?
  • PbootCMS幻灯片轮播图标签调用与参数详解
  • PbootCMS指定内容多图调取与标签详解
  • PbootCMS运行环境要求及PHP扩展配置详解
  • CS501芯片,Typec转DP 8k60方案,替代乐德瑞LDR6500方案
  • Step-Audio-R1:音频深度推理模型;Soul 冲刺港交所,「AI+沉浸式社交平台」,累计注册用户达 3.9 亿丨日报
  • 2025年EUDR法规培训十大优质机构推荐,合规专家深度解析
  • A. k-Amazing Numbers
  • 太阳风暴下的数字暗涌:空间天气如何触发软件漏洞
  • 内外网文件摆渡系统是什么?主要有哪几点核心功能?
  • 新能源汽修维修方面的学校TOP5权威推荐:深度测评指南,助力
  • EXCEL匹配某一个单元格包含的字符,整行标记颜色
  • PbootCMS指定内容调取与标签详解
  • 2025国产CMDB厂商选型指南:自主可控时代的配置管理新范式
  • 2025年西洋参片定制厂家权威推荐榜单:西洋参粉生产/长白山西洋参片/西洋参片代工源头厂家精选
  • 委托仓库
  • 【IEEE出版 | EI检索】第五届计算机、物联网与控制工程国际学术会议(CITCE 2025)
  • 必看!2025年口碑好的新疆旅游服务排行榜
  • 减肥最快最有效方法!2025年代谢减肥产品深度评估,破解秋冬难瘦和反弹魔咒