spring循环依赖,解决beans in the application context form a cycle

12 篇文章 0 订阅
11 篇文章 0 订阅

spring循环依赖简单理解就是类A中引用B,B引用C,C中引用了A,这样构成了循环。

spring中解决循环依赖主要靠三级本地缓存解决

第一级缓存singletonObjects里面放置的是缓存实例化好的单例对象。

第二级earlySingletonObjects里面存放的是提前曝光的单例对象(没有完全装配好)。

第三级singletonFactories里面存放的是要被实例化的对象的对象工厂

/** Cache of singleton objects: bean name --> bean instance(缓存单例实例化对象的Map集合) */
 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64); 
  
 /** Cache of singleton factories: bean name --> ObjectFactory(单例的工厂Bean缓存集合) */
 private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>(16); 
  
 /** Cache of early singleton objects: bean name --> bean instance(早期的单身对象缓存集合,未完全事例好) */
 private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16); 
  
 /** Set of registered singletons, containing the bean names in registration order(单例的实例化对象名称集合) */
 private final Set<String> registeredSingletons = new LinkedHashSet<String>(64); 

具体流程原理参考:https://www.jianshu.com/p/16a44c25c9d9       

具体报错的例子是这样的:

QueueMessageCommService通过构造方法注入QueueFieldService,但是QueueFieldService中注入的bean中也注入了QueueMessageCommService,构成了循环。

spring在自动装载时报错beans in the application context form a cycle,与final有关(jdk1.8不同版本有的报错,有的不报错)。

如下图修改后:就不报错了,完全交给spring去装载注入Bean

 

解决循环依赖的办法:

1、@Autowired   交给spring完全处理

2、setter 单例方式singleton  处理这种方式是bean先实例化后再进行属性填充,这样避免了实例时形成循环

3、setter 原型prototype  代表是有状态的bean,spring 无法完成依赖注入,因为不对它进行缓存(三级缓存的对象)

这样就需要调用Bean中方法(有引用对象使用)之前,先掉set方法赋值(引用对象),防止出现null。

scope="prototype" 意思是 每次请求都会创建一个实例对象。两者的区别是:有状态的bean都使用Prototype作用域,无状态的一般都使用singleton单例作用域。

     spring事例化图:

更多setter方式详细见:https://blog.csdn.net/u010644448/article/details/59108799

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
回答: 当在Spring初始化bean的过程中,如果存在循环依赖的情况,就会出现"The dependencies of some of the beans in the application context form a cycle"的错误。这个错误表示应用程序上下文中的一些bean存在循环依赖关系。\[2\]\[3\]循环依赖是指两个或多个bean之间相互依赖,形成一个闭环。在这种情况下,Spring无法确定先初始化哪个bean,因此会导致循环依赖错误的发生。为了解决这个问题,可以使用@Lazy注解来延迟加载其中一个bean,从而打破循环依赖关系。\[1\]在代码中,可以使用@Autowired和@Lazy注解来标记需要延迟加载的bean,例如:@Autowired @Lazy private MqttAcceptClient mqttAcceptClient; 这样就可以解决Spring在初始化bean时不知道先初始化哪个的问题。 #### 引用[.reference_title] - *1* *3* [【报错解决】The dependencies of some of the beans in the application context form a cycle:](https://blog.csdn.net/weixin_44361204/article/details/123778790)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [The dependencies of some of the beans in the application context form a cycle 解决方案](https://blog.csdn.net/weixin_46044901/article/details/122826554)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值