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

怎么做网站搜索框搜索营销策划公司取名大全

怎么做网站搜索框搜索,营销策划公司取名大全,wordpress 导购,redhat7部署wordpressSpring 通过 三级缓存 和 提前暴露对象引用 的机制解决单例 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/243898.html

相关文章:

  • 做壁纸网站好三只松鼠搜索引擎推广
  • 网站制作动态网站建站在线制作
  • php网站开发需要学哪些网络营销的特征
  • 网站建设广告方案市场营销在线课程
  • 重庆网站建设seo长沙seo优化排名
  • 网站内链规划外贸seo网站建设
  • 旅游网站建设的方法网络建设推广
  • 网站建设 顺德谷歌paypal官网入口
  • 厦门市建设局网站百度区域代理
  • 做背景音乐的版权网站百度站内搜索提升关键词排名
  • 新闻网站网页设计艾滋病多久可以查出来
  • 适合做网站开发的电脑配置百度allin 人工智能
  • 建设一个公司网站大概多少钱项目推广渠道有哪些
  • 滕州做网站哪家好b2b免费发布网站大全
  • 哪个行业该做网站但是没有做友链交换平台
  • 做网站开发学什么关键词优化计划
  • 怎么做自己的微信网站上海百度推广排名优化
  • 微信朋友圈推广怎么做网站刷粉网站推广马上刷
  • wordpress 栏目不同模板网络营销推广seo
  • 柯城建设局网站天津百度seo代理
  • 济南网站建设公司晟创未来网站的优化与推广分析
  • 成都网站建设是什么网页设计教程
  • 卖水果做哪个网站好广州竞价托管公司
  • 寮步营销型网站建设百度推广客服投诉电话
  • 宁波网站建设制作的公司南京百度seo
  • 电子商务网站建设需要知识多层次网络营销合法吗
  • 青岛做网站电话必应bing搜索引擎
  • 珠海多语种网站制作广州网站营销优化qq
  • 网站开发培训成都中国最新军事新闻最新消息
  • 响应式网站建设特征网络推广的主要工作内容