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

企业建站公司实力对比网页搜索关键字

企业建站公司实力对比,网页搜索关键字,汕头网站制作,网站维护运行建设报告Spring 通过 三级缓存 和 提前暴露对象引用 的机制解决单例 Bean 的循环依赖问题。以下是详细原理和实现流程: 一、循环依赖的场景 假设存在以下相互依赖的 Bean: Component public class A {Autowiredprivate B b; }Component public class B {Autowi…

Spring 通过 三级缓存提前暴露对象引用 的机制解决单例 Bean 的循环依赖问题。以下是详细原理和实现流程:


一、循环依赖的场景

假设存在以下相互依赖的 Bean:

@Component
public class A {@Autowiredprivate B b;
}@Component
public class B {@Autowiredprivate A a;
}

此时 Spring 需要处理 A → B → A 的循环依赖。


二、Spring 的解决机制

1. 三级缓存

Spring 使用三级缓存存储不同状态的 Bean:

缓存名称作用
singletonObjects存储完全初始化后的单例 Bean(一级缓存)
earlySingletonObjects存储早期暴露的 Bean(未完成属性填充和初始化,二级缓存)
singletonFactories存储 Bean 的 ObjectFactory(用于生成早期引用,三级缓存)
2. Bean 创建流程(以 A → B → A 为例)

步骤 1:创建 Bean A

  1. 实例化 A(调用构造函数,但属性未填充)。
  2. 将 A 的 ObjectFactory 放入 三级缓存singletonFactories)。
  3. 开始填充 A 的属性,发现依赖 B。

步骤 2:创建 Bean B

  1. 实例化 B(调用构造函数,属性未填充)。
  2. 将 B 的 ObjectFactory 放入 三级缓存
  3. 开始填充 B 的属性,发现依赖 A。

步骤 3:解决依赖 A

  1. 三级缓存 中获取 A 的 ObjectFactory,生成 A 的早期引用。
  2. 将 A 的早期引用放入 二级缓存earlySingletonObjects),并从三级缓存中移除。
  3. 将 A 的早期引用注入到 B 中,完成 B 的初始化。
  4. 将 B 的完整实例放入 一级缓存singletonObjects)。

步骤 4:完成 Bean A 的初始化

  1. 将已注入 B 的 A 实例继续初始化。
  2. 将 A 的完整实例从 二级缓存 移到 一级缓存

三、核心源码解析

关键类DefaultSingletonBeanRegistry
缓存操作

// 从缓存获取 Bean
protected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName); // 一级缓存if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {singletonObject = this.earlySingletonObjects.get(beanName); // 二级缓存if (singletonObject == null && allowEarlyReference) {synchronized (this.singletonObjects) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); // 三级缓存if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}}return singletonObject;
}

四、限制条件

1. 仅支持单例(Singleton)作用域的 Bean

原型(Prototype)作用域的 Bean 无法解决循环依赖,Spring 直接抛出 BeanCurrentlyInCreationException

2. 不支持构造器注入的循环依赖

构造器注入的循环依赖无法解决(实例化阶段就需要依赖对象,但此时依赖的 Bean 未创建)。
错误示例

@Component
public class A {private B b;public A(B b) { this.b = b; } // 构造器注入导致循环依赖无法解决
}
3. 需要启用代理

• 若 Bean 被 AOP 代理(如通过 @Async@Transactional),需确保代理对象能正确暴露到缓存中。


五、如何避免循环依赖?

  1. 代码设计优化
    • 避免双向依赖,改为单向依赖。
    • 使用 @Lazy 延迟加载(将依赖标记为惰性初始化)。
    • 通过事件驱动(ApplicationEvent)解耦 Bean。

  2. 依赖注入方式
    • 优先使用 Setter 注入 而非构造器注入。

  3. 示例:使用 @Lazy

    @Component
    public class A {@Autowired@Lazy // 延迟注入 B 的代理对象private B b;
    }
    

六、总结

机制说明
三级缓存通过缓存不同状态的 Bean 解决循环依赖
提前暴露引用在 Bean 未完成初始化前,提前将引用暴露给其他 Bean 使用
单例限制仅支持单例 Bean,原型 Bean 和构造器注入的循环依赖无法解决

最佳实践:优先通过代码设计避免循环依赖,仅在必要场景下依赖 Spring 的自动解决机制。

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

相关文章:

  • 深汕特别合作区是什么意思seo分析与优化实训心得
  • 广西南宁相亲网广州抖音seo公司
  • 体育论坛网站建设市场推广外包团队
  • 健身器材网站模板武汉seo软件
  • 穿越火线外挂购买网站中国网站建设公司前十名
  • 仙居网站建设贴吧浏览器看b站
  • 什么是企业型网站西安seo网站关键词优化
  • 怎么给网站做域名重定向怎么提升关键词的质量度
  • 专业专业的网站开发宁波seo推广优化公司
  • dw怎么把网站做的漂亮网站正能量免费推广软件
  • 西藏建设厅网站女教师网课入06654侵录屏
  • 萍乡做网站的公司常德政府网站
  • 元氏网站制作百度上做推广怎么做
  • 宁夏网站建设多少钱second是什么意思
  • wordpress导航页面模板下载地址南京seo圈子
  • 怎么做能让网站收录的快必应搜索
  • 网站建设和优化需要几个人网站推广优化网址
  • 光山网站建设网站模板价格
  • 素马网站建设费用差距互联网推广怎么找渠道
  • 网站建设要注册哪些商标类别互联网广告营销
  • 怎么创网站百度官网认证价格
  • 红豆梧州论坛seod的中文意思
  • 阿里云wordpress建站常州网络推广seo
  • 长沙岳麓区广告公司宁波seo哪家好快速推广
  • wordpress菜单不兼容关键词排名优化公司
  • 上海市建设安全协会网站孟 侠友情链接交换的方法
  • 沧州做网站推广公司百度怎么发布短视频
  • wordpress 邮件投稿信息流优化师简历模板
  • 旅游攻略网站模板seo博客
  • 大型网站 解决方案 技术网络营销有哪些形式