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

天津建设网站的公司简介陇南市武都区住房和城乡建设网站

天津建设网站的公司简介,陇南市武都区住房和城乡建设网站,济南房地产网站建设,深圳网络推广市场Spring解决循环依赖的核心机制:三级缓存 Spring通过三级缓存(三级Map)提前暴露未完全初始化的Bean,解决循环依赖问题。核心思想是“提前暴露引用”,允许Bean在构造完成后但未初始化前被其他Bean引用。 三级缓存的作用…

Spring解决循环依赖的核心机制:三级缓存

Spring通过三级缓存(三级Map)提前暴露未完全初始化的Bean,解决循环依赖问题。核心思想是“提前暴露引用”,允许Bean在构造完成后但未初始化前被其他Bean引用。


三级缓存的作用

  1. singletonObjects(一级缓存)
    存放完全初始化好的单例Bean,可以直接使用。

  2. earlySingletonObjects(二级缓存)
    存放早期暴露的Bean(已实例化但未初始化),用于解决循环依赖。

  3. singletonFactories(三级缓存)
    存放Bean的工厂对象(ObjectFactory),用于生成Bean的早期引用(可能包含代理对象)。


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

  1. 创建Bean A

    • 实例化A(调用构造器),此时A对象未初始化(属性为空)。

    • 将A的工厂对象放入三级缓存(addSingletonFactory)。

    • 开始填充A的属性,发现依赖B,触发B的创建。

  2. 创建Bean B

    • 实例化B,同样将B的工厂对象放入三级缓存。

    • 填充B的属性时,发现依赖A,触发从缓存获取A的流程:

      • 从一级缓存查找A → 不存在。

      • 从二级缓存查找A → 不存在。

      • 从三级缓存获取A的工厂对象,生成A的早期引用 → 成功获取,将A的引用存入二级缓存,并移除三级缓存中的工厂。

    • B完成属性填充和初始化,放入一级缓存。

  3. 继续完成A的初始化

    • B创建完成后,A的属性B被注入。

    • A完成初始化,从二级缓存移除,并存入一级缓存。


关键源码实现

  • DefaultSingletonBeanRegistry:定义了三级缓存的Map结构。

  • getSingleton()方法:按三级→二级→一级的顺序查找Bean。

  • addSingletonFactory()方法:将Bean工厂加入三级缓存。

  • getEarlyBeanReference()方法:通过工厂生成早期引用(处理AOP代理)。


限制条件

  1. 必须是单例(Singleton)
    原型(Prototype)作用域的Bean无法解决循环依赖。

  2. 不能是构造器注入
    若依赖通过构造器注入,Bean未实例化完成前无法暴露引用,Spring会抛出BeanCurrentlyInCreationException

  3. 需要启用字段/Setter注入
    通过属性注入时,Spring有机会在实例化后干预依赖注入。


为何需要三级缓存(而不是两级)?

  • 处理AOP代理:三级缓存中的ObjectFactory可以返回代理对象(如果需要AOP),确保依赖注入的是最终代理对象,而非原始对象。

  • 性能优化:避免重复创建代理对象,保证单例的唯一性。


面试回答示例

“Spring通过三级缓存解决循环依赖问题。当Bean实例化后、初始化前,Spring会将其工厂对象存入三级缓存。若其他Bean在填充属性时发现循环依赖,会通过这个工厂提前获取Bean的早期引用。需要注意的是,这种机制仅适用于单例且通过Setter或字段注入的Bean,构造器注入的循环依赖无法解决。底层通过DefaultSingletonBeanRegistry类中的三个Map实现,结合Bean的生命周期方法确保依赖的正确注入。”

Spring 中设计了三级缓存来解决

循环依赖问题,当我们去调用 getBean()方法的时候,Spring 会 先从一级缓存中去找到目标 Bean,如果发现一级缓存中没有便会去二级缓存中去找,而如果一、二级 缓存中都没有找到,意味着该目标 Bean 还没有实例化。于是,Spring 容器会实例化目标 Bean(PS: 刚初始化的 Bean 称为早期 Bean) 。然后,将目标 Bean 放入二级缓存中,同时,加上标记是否存在 循环依赖。如果不存在循环依赖便会将目标 Bean 存入到二级缓存,否则,便会标记该 Bean 存在循环 依赖,然后将等待下一次轮询赋值,也就是解析@Autowired 注解。等@Autowired 注解赋值完成后 (PS:完成赋值的 Bean 称为成熟 Bean) ,会将目标 Bean 存入到一级缓存。 这里我可以做个总结,我们来看这张图 Spring 一级缓存中存放所有的成熟 Bean, 二级缓存中存放所有的早期 Bean,先取一级缓存,再去二级缓存。

面试官:那么,前面有提到三级缓存,三级缓存的作用是什么? 三级缓存是用来存储代理 Bean,当调用 getBean()方法时,发现目标 Bean 需要通过代理工厂来创建, 此时会将创建好的实例保存到三级缓存,最终也会将赋值好的 Bean 同步到一级缓存中。 面试官:Spring 中哪些情况下,不能解决循环依赖问题? 1.多例 Bean 通过 setter 注入的情况,不能解决循环依赖问题 2.构造器注入的 Bean 的情况,不能解决循环依赖问题 3.单例的代理 Bean 通过 Setter 注入的情况,不能解决循环依赖问题 4.设置了@DependsOn 的 Bean 的情况,不能解决循环依赖问题


文章转载自:

http://gM0z8Kyi.phhqL.cn
http://lSJQb3H1.phhqL.cn
http://KDCZS0w4.phhqL.cn
http://tkIvPQLn.phhqL.cn
http://o9ZnfVOu.phhqL.cn
http://zDICiUs4.phhqL.cn
http://iI4WAkJX.phhqL.cn
http://c8GWy2MU.phhqL.cn
http://ukZ1nJsO.phhqL.cn
http://wx2LtHip.phhqL.cn
http://wjQtzv3S.phhqL.cn
http://4ITNBZ6m.phhqL.cn
http://VelpuJaW.phhqL.cn
http://cnp5mtJC.phhqL.cn
http://PCrjluFO.phhqL.cn
http://UiUb081h.phhqL.cn
http://FNGnp7rr.phhqL.cn
http://LUH81a6q.phhqL.cn
http://prVm1O1r.phhqL.cn
http://DOZfP4vp.phhqL.cn
http://YkVNSPsu.phhqL.cn
http://26rI9kkS.phhqL.cn
http://JJj36CvF.phhqL.cn
http://NS0dNHDy.phhqL.cn
http://a8S2TTP0.phhqL.cn
http://hcmHKwKB.phhqL.cn
http://KTStQOto.phhqL.cn
http://s4E9wbZf.phhqL.cn
http://x1sunIZE.phhqL.cn
http://MD3nm9Ps.phhqL.cn
http://www.dtcms.com/wzjs/629896.html

相关文章:

  • 网站建设方案书格式华为网站建设目标
  • 做T恤卖网站如何添加网站为信任站点
  • 网站规划的原则是什么有好的网址推荐吗
  • 怎样用网站做单笔外贸深圳网站建设定制平台
  • php中网站不同模板后台逻辑代码怎么管理注册新公司网上核名网站
  • 北京专门做网站的湘潭网站建设价格
  • 北京做网站哪家公司最好做的好的淘宝客网站
  • 教着做美食的网站志鸿优化网下载
  • 关于网站开发的毕业设计深圳网页制作电话
  • 网站seo优化是什么国外网站域名查询
  • 宁波行业网站建设广州专业做标书公司
  • 做自媒体可利用的国外网站竞价运营是做什么的
  • 网站流量排名查询工具四川餐饮培训学校排名
  • 旅游网站建设问题网站建设公司如何收费
  • 服装公司网站策划方案网页设计实验报告结果分析
  • 苏宁易购网站建设建议永康市网站建设
  • 竞价网站怎么做seo小卖部做网站
  • 免费做app网站建设百度扫一扫识别图片
  • 修改网站j广州网络公司网站全部用根目录
  • 个人网站源码进一品资源杭州哪家公司可以做网站
  • 网站内容的编辑和更新怎么做邯郸铸邯网络信息科技有限公
  • 北京如何优化网站大学生平面设计作品集
  • 网站兼容浏览器服务免费建英文网站
  • 上海网站建设费用wordpress 发布api
  • 网站如何备案流程腾讯云服务器租用费用
  • dnf怎么做盗号网站个人网站尺寸
  • 外链网盘网站阀门网站设计
  • 有什么网站做的比较高大上百度推广平台登陆
  • 宝安商城网站建设做视频网站成本高吗
  • 闲置物品交易网站怎么做的加强司法机关网站建设