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

网站的代理页面怎么做搜狗收录提交入口

网站的代理页面怎么做,搜狗收录提交入口,网站建设开发合同模板,深圳网址网站建设公司一、什么是循环依赖? 循环依赖(Circular Dependency) 指两个或多个组件相互直接或间接依赖,形成闭环引用关系。在Spring框架中,主要表现为Bean之间的相互注入。 1. 循环依赖的三种典型形态 // 案例1:直接…

一、什么是循环依赖?

循环依赖(Circular Dependency) 指两个或多个组件相互直接或间接依赖,形成闭环引用关系。在Spring框架中,主要表现为Bean之间的相互注入。

1. 循环依赖的三种典型形态

// 案例1:直接循环依赖(A↔B)
@Component
class A {@Autowiredprivate B b;
}@Component
class B {@Autowiredprivate A a;
}// 案例2:间接循环依赖(A→B→C→A)
@Component
class C {@Autowiredprivate A a;
}// 案例3:自我依赖(极端情况)
@Component
class Self {@Autowiredprivate Self self; // 实际开发中应避免
}

2. 循环依赖的危害

  • 启动失败:Spring容器初始化时可能抛出BeanCurrentlyInCreationException
  • 代码耦合:破坏模块化设计原则
  • 调试困难:难以追踪依赖关系

二、Spring的解决之道:三级缓存机制

1. 三级缓存结构

Spring通过三级缓存解决单例Bean的循环依赖问题:

缓存名称数据结构存储内容
singletonObjects(一级缓存)ConcurrentHashMap完全初始化好的Bean
earlySingletonObjects(二级缓存)HashMap早期暴露对象(未完成属性注入)
singletonFactories(三级缓存)HashMap对象工厂(用于生成早期对象)

2. 核心解决流程

以A和B相互依赖为例:

Spring A B 三级缓存 二级缓存 一级缓存 开始创建A 将A的ObjectFactory放入三级缓存 发现需要注入B 开始创建B 将B的ObjectFactory放入三级缓存 发现需要注入A 通过A的ObjectFactory获取早期A 将早期A提升到二级缓存 完成B的初始化 注入完整的B 完成A的初始化 Spring A B 三级缓存 二级缓存 一级缓存

三、源码级解析

1. 核心源码位置

  • DefaultSingletonBeanRegistry:管理三级缓存
  • AbstractAutowireCapableBeanFactory:Bean创建主流程

2. 关键代码片段

// 创建Bean的核心方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Object[] args) {// 1. 实例化对象(此时对象属性为空)BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);// 2. 将ObjectFactory加入三级缓存(解决循环依赖的关键)addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));// 3. 属性注入(可能触发依赖Bean的创建)populateBean(beanName, mbd, instanceWrapper);// 4. 初始化exposedObject = initializeBean(beanName, exposedObject, mbd);return exposedObject;
}// 三级缓存写入逻辑
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {this.singletonFactories.put(beanName, singletonFactory);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName);}}
}

四、构造器注入 vs 属性注入

1. 构造器注入无法解决循环依赖

@Component
class C {private D d;@Autowiredpublic C(D d) { this.d = d; } // 构造器注入
}@Component
class D {private C c;@Autowiredpublic D(C c) { this.c = c; } // 抛出BeanCurrentlyInCreationException
}

2. 原因分析

  • 构造器注入发生在实例化阶段,此时对象尚未创建完成,无法放入三级缓存
  • 属性注入发生在实例化之后,此时已通过三级缓存暴露早期引用

五、解决方案的局限性

1. 作用域限制

作用域类型是否支持循环依赖原因
Singleton(默认)三级缓存机制支持
Prototype每次获取新对象,无法提前暴露
Request/Session作用域生命周期短且不固定

2. 代理对象问题

  • 若Bean需要AOP代理,必须使用CGLIB代理(JDK代理需要接口)
  • 解决方法:配置spring.aop.proxy-target-class=true

六、开发建议与最佳实践

1. 避免循环依赖的方法

  • 模块化设计:遵循单一职责原则
  • 依赖方向控制:保持单向依赖(A→B→C)
  • 接口抽象:通过接口解耦具体实现
  • 延迟加载:使用@Lazy注解
@Component
class E {@Lazy // 延迟注入@Autowiredprivate F f;
}

2. 必须使用循环依赖时

  1. 确保使用属性注入(setter/字段注入)
  2. 所有相关Bean必须为单例
  3. 避免在@PostConstruct方法中访问依赖Bean

七、终极解决方案:重新设计

当遇到复杂的循环依赖时,应考虑以下重构方案:

重构方法实施案例
引入第三方类将公共逻辑提取到新类C,让A、B都依赖C
使用事件驱动通过ApplicationEvent解耦
转换为方法调用使用ApplicationContext.getBean()
接口分层定义服务接口与实现类分离

总结

Spring通过三级缓存机制巧妙地解决了单例Bean的循环依赖问题,但开发者应认识到:

  1. 这是框架层面的补救措施,而非设计推荐
  2. 构造器注入的循环依赖无法解决
  3. 原型作用域的Bean不支持循环依赖
  4. 复杂项目应通过代码重构消除循环依赖
http://www.dtcms.com/wzjs/462182.html

相关文章:

  • 想做个网站不知道怎么做0元做游戏代理
  • 宁波网站设计推广培训班独立站seo是什么意思
  • 做网站在什么地方找搜索引擎外部链接优化
  • 冀州市网站建设八爪鱼磁力搜索引擎
  • 网站模板下载软件软文推广的标准类型
  • 广州网站制作是什么友情链接代码美化
  • 网站建设与规划新闻稿撰写
  • 婚庆网站源码seo推广优化外包公司
  • 校园网站建设用什么软件写网络软文范文
  • 西安网站建设开发公司武汉seo和网络推广
  • 附近的网站设计制作价格快速提升排名seo
  • 旅游网站建设费用免费html网页模板
  • 网站敏感关键词.txt郑州seo排名扣费
  • 做网站学什么代码软文营销的特点
  • 荆州网站建设推荐网站注册免费
  • 城乡建设学校网站网站优化推广软件
  • 个人建网站成本你就知道首页
  • 安徽网站建设论坛网络舆情监测与研判
  • 重庆网站建设外包网络广告营销的概念
  • wordpress 引入样式个人如何优化网站有哪些方法
  • b2b2c网站怎么做企业网络营销推广平台
  • 做网站应达到什么效果关键词搜索量查询
  • 电子商务网站的数据库怎么做google怎么推广
  • 朝阳网站建设多少钱影视网站怎么优化关键词排名
  • 杭州网站排名优化360优化大师官方下载最新版
  • wordpress博客优秀南宁百度seo排名
  • 佛山高端网站设计2023年3月份疫情严重
  • 开发公司移交柴油发动机需要具备哪些条件沈阳seo建站
  • 阅读网站建设网络推广方案
  • 怎么在网上做网站公司怎么做网站推广