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

能够做冶金工程毕业设计的网站做网站用的编程工具

能够做冶金工程毕业设计的网站,做网站用的编程工具,学做ppt的网站有哪些,上海大 小企业网站制作引言 在Spring Boot开发中,你是否遇到过这样的错误信息? The dependencies of some of the beans in the application context form a cycle 这表示你的应用出现了循环依赖。尽管Spring框架通过巧妙的机制解决了部分循环依赖问题,但在实际开…
引言

在Spring Boot开发中,你是否遇到过这样的错误信息?
The dependencies of some of the beans in the application context form a cycle
这表示你的应用出现了循环依赖。尽管Spring框架通过巧妙的机制解决了部分循环依赖问题,但在实际开发中(尤其是使用构造器注入时),开发者仍需警惕此类问题。本文将深入探讨循环依赖的根源,分析Spring的解决策略,并提供多种实战解决方案。


一、什么是循环依赖?

循环依赖指两个或多个Bean相互依赖对方,形成一个闭环。例如:

  • Bean A​ 的创建需要注入 ​Bean B
  • Bean B​ 的创建又需要注入 ​Bean A

此时,Spring容器在初始化Bean时会陷入“死循环”。以下是一个典型示例:

@Service
public class ServiceA {private final ServiceB serviceB;public ServiceA(ServiceB serviceB) { // 构造器注入ServiceBthis.serviceB = serviceB;}
}@Service
public class ServiceB {private final ServiceA serviceA;public ServiceB(ServiceA serviceA) { // 构造器注入ServiceAthis.serviceA = serviceA;}
}

启动应用时,Spring会抛出异常:
BeanCurrentlyInCreationException: Error creating bean with name 'serviceA': Requested bean is currently in creation


二、Spring如何解决循环依赖?

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

  1. 一级缓存​(singletonObjects):存放完全初始化好的Bean。
  2. 二级缓存​(earlySingletonObjects):存放提前曝光的半成品Bean(仅实例化,未填充属性)。
  3. 三级缓存​(singletonFactories):存放Bean的工厂对象,用于生成半成品Bean。

解决流程​(以A和B相互依赖为例):

  1. 创建A时,先实例化A(未填充属性),并将A的工厂放入三级缓存。
  2. 填充A的属性时发现需要B,开始创建B。
  3. 创建B时,实例化B后,发现需要A,此时从三级缓存中通过工厂获取A的半成品对象。
  4. B完成初始化,放入一级缓存。
  5. A继续填充B的实例,完成初始化,放入一级缓存。

关键限制​:该机制仅支持单例Bean通过属性注入的场景。​构造器注入会直接失败!


三、为何构造器注入会导致循环依赖失败?

构造器注入要求Bean在实例化阶段立即获得依赖对象,而三级缓存机制需要在属性注入阶段解决依赖。因此,当两个Bean都使用构造器注入时,Spring无法提前曝光半成品Bean,导致循环依赖无法解决。


四、解决方案:打破循环依赖的四种方法
1. ​改用Setter/Field注入(谨慎使用)​

将构造器注入改为Setter或字段注入,允许Spring延迟注入依赖:

@Service
public class ServiceA {private ServiceB serviceB;@Autowired // Setter注入public void setServiceB(ServiceB serviceB) {this.serviceB = serviceB;}
}
  • 优点​:快速解决问题。
  • 缺点​:破坏了不可变性(字段非final),且可能掩盖设计问题。
2. ​使用@Lazy延迟加载

在依赖对象上添加@Lazy,告知Spring延迟初始化Bean:

@Service
public class ServiceA {private final ServiceB serviceB;public ServiceA(@Lazy ServiceB serviceB) {this.serviceB = serviceB; // 实际注入的是代理对象}
}
  • 原理​:Spring生成代理对象,只有在首次调用时才会真正初始化目标Bean。
  • 适用场景​:解决构造函数注入的循环依赖。
3. ​重新设计代码结构

通过分层或提取公共逻辑,消除循环依赖:

  • 方案一​:引入中间层(如ServiceC),将A和B的共同依赖转移到C。
  • 方案二​:使用事件驱动(ApplicationEvent),解耦直接依赖。
// 事件驱动示例
@Service
public class ServiceA {@Autowiredprivate ApplicationEventPublisher eventPublisher;public void doSomething() {eventPublisher.publishEvent(new EventA());}
}@Service
public class ServiceB {@EventListenerpublic void handleEventA(EventA event) {// 处理事件}
}
4. ​使用ObjectProvider(推荐)​

在构造器中注入ObjectProvider,按需获取依赖:

@Service
public class ServiceA {private final ServiceB serviceB;public ServiceA(ObjectProvider<ServiceB> serviceBProvider) {this.serviceB = serviceBProvider.getIfUnique();}
}
  • 优点​:保持构造器注入的不可变性,显式控制依赖获取时机。
  • 注意​:需确保依赖Bean存在且唯一。

五、最佳实践与预防措施
  1. 优先使用构造器注入​:保持Bean的不可变性和明确依赖,但需警惕循环依赖。
  2. 定期检测循环依赖​:
    • 使用IDE插件(如IntelliJ的Circular Dependencies分析)。
    • 通过Maven/Gradle插件(如spring-boot-dependencies-analysis)。
  3. 代码分层规范​:
    • 严格遵循分层架构(Controller → Service → Repository)。
    • 避免同一层内的Bean相互依赖。
  4. 单元测试验证​:编写集成测试,验证Bean的初始化过程。
@SpringBootTest
public class CircularDependencyTest {@Autowiredprivate ApplicationContext context;@Testvoid contextLoads() {// 若启动无异常,则通过测试assertNotNull(context.getBean(ServiceA.class));}
}

六、总结

循环依赖是Spring开发中的常见陷阱,其本质是代码设计问题。尽管Spring提供了部分解决方案,但重构代码消除循环依赖才是根本之道。通过合理使用注入方式、代码分层和工具检测,开发者可以有效避免此类问题,构建高可维护性的应用。

记住​:

  • 慎用@Lazy和Setter注入,它们可能掩盖设计缺陷。
  • 构造器注入 + 合理分层 = 更健壮的系统!

文章转载自:

http://YpFzyn0j.kcwkt.cn
http://I7VddFgQ.kcwkt.cn
http://IDTbmHO4.kcwkt.cn
http://6j1pYCbT.kcwkt.cn
http://Y0eQ2r7A.kcwkt.cn
http://8hLBqDZG.kcwkt.cn
http://J86PF1vO.kcwkt.cn
http://pyt4f8NU.kcwkt.cn
http://9JLOQ5mH.kcwkt.cn
http://3VHvxiSL.kcwkt.cn
http://bt7551qu.kcwkt.cn
http://XI8ECoZa.kcwkt.cn
http://H6XXfFkC.kcwkt.cn
http://Y0TE4uZx.kcwkt.cn
http://rPbmAzdR.kcwkt.cn
http://XGPQlz8W.kcwkt.cn
http://uReKRAWj.kcwkt.cn
http://g7iSxWp2.kcwkt.cn
http://Tw4xtzzX.kcwkt.cn
http://26bCGVzX.kcwkt.cn
http://unojz4Xq.kcwkt.cn
http://DSh0EOx7.kcwkt.cn
http://3BzpWb77.kcwkt.cn
http://CmJmZ6xg.kcwkt.cn
http://txNbP44m.kcwkt.cn
http://mpETczV7.kcwkt.cn
http://AYL9fdRI.kcwkt.cn
http://fZqEKaD4.kcwkt.cn
http://V7T5rMsI.kcwkt.cn
http://H0JZ8KJj.kcwkt.cn
http://www.dtcms.com/wzjs/738702.html

相关文章:

  • 公司网站是否有必要销售产品做动图的网站知乎
  • 做电商的进货网站古镇企业网站建设
  • 网站可以用中国二字做抬头吗代理网店加盟
  • 网站文章关键字密度宁波黄页网
  • 织梦文章类网站模板做一个商务平台网站的费用
  • 门户网站建设的请示平面设计公司简介怎么写
  • 福田做网站优化乐云seo高端自适应网站开发
  • 记事本做网站怎么改字体网站设计的收费
  • 网站维护 推广外贸网站平台
  • 东莞做购物网站入门网站分析应该怎么做
  • 网站建设实践报告3000字计算机类十大含金量证书
  • 滕建建设集团网站哈尔滨网站建设价格
  • 网站建设公司河南郑州应用软件商店下载
  • 上海网站制作团队微信号 网站模板
  • 家电照明电子通用网站模板网站tag设计
  • 商城网站备案能通过吗建设部考试网站
  • 如何建购物网站重庆网站空间键词排名
  • 如何创建网站的二维码网站推广软件下载安装免费
  • 建设个网站要多少钱仕德伟做的网站
  • 搭建网上商城湖南网站优化外包费用
  • 做特卖网站有哪些浙江建站优化品牌
  • 建设网站属于什么费用做一页简单的h5多少钱
  • 网站建设调查表南京百度快速排名优化
  • 成都网站建设 哪家比较好建设银行信用卡中心
  • 模仿茶叶的网站制作网站建设优化公司哪家好
  • 网站开发应用网站开发 与 网页设计的区别
  • 网站产品图片尺寸云南省建设厅建筑业信息网
  • 建商城宁波seo网络推广优化价格
  • 肯德基网站建设的目标搜狗推广下架
  • 分类信息网站营销百度建站云南服务中心