你们好,我是金金金。

场景

- 启动服务时,报错:应用程序上下文中的某些bean的依赖关系形成了一个循环
 
循环依赖
依赖循环指的是两个或多个类之间相互依赖的情况,即类A依赖类B,同时类B也依赖类A。 这种情况会导致编译器无法确定类的加载顺序,从而产生编译错误

- 如上图:
BeanA类依赖了BeanB类,同时BeanB类又依赖了BeanA类。这种依赖关系形成了一个闭环,这种依赖关系就称之为循环依赖 
排查
从报错信息可以得知,这是一个依赖循环的问题~,问题出在
MqConfig和rabbitTemplateConfigurer这两者形成了相互依赖,从而产生了依赖循环
- 从报错得知,整理的依赖顺序如下~
 
payController依赖于payOrderServiceImpl
payOrderServiceImpl依赖于MqConfig
MqConfig依赖于rabbitTemplate
rabbitTemplate依赖于rabbitTemplateConfigurer
rabbitTemplateConfigurer依赖于MqConfig
- 好,一步步来,走起~
 
-  
我先贴出
MqConfig和RabbitMqHelper代码Mq.config.java

RabbitMqHelper.java

 -  
从报错开始排查,首先看
PayController,这里面使用了IPayOrderService那必然有依赖关系
 -  
再继续看
payOrderServiceImpl
- PayOrderServiceImpl里面使用到了rabbitMqHelper,而rabbitMqHelper又是在MqConfig里面注册为一个Bean的,所以也就是为什么payOrderServiceImpl依赖于MqConfig的原因了~
 
 -  
继续走,我们看一下
MqConfig,其实上面也有贴出MqConfig的详细代码了,我这里再放一遍
- 从报错显示,
MqConfig依赖于rabbitTemplate,这很明显了,因为我MqConfig里面有使用到rabbitTemplate,所以也存在着依赖关系 
 - 从报错显示,
 -  
继续,我们可以看到
rabbitTemplate依赖于rabbitTemplateConfigurer,这里得看一下源码了,跟着节奏,走起-  
我们来到
RabbitAutoConfiguration里面,可以看到三个内部类
 -  
根据报错得知
rabbitTemplate依赖于rabbitTemplateConfigurer,来看下RabbitTemplateConfiguration这个内部类究竟是什么?
- 现在就很明显了,可以看到
rabbitTemplate就在RabbitTemplateConfiguration内部类当中,rabbitTemplate在这个内部类当中注册为了Bean,而且这个Bean是依赖于RabbitTemplateConfigurer的,所以也就是为什么rabbitTemplate依赖于rabbitTemplateConfigurer 
 - 现在就很明显了,可以看到
 
 -  
 -  
好,现在也就是最后一点,
rabbitTemplateConfigurer为什么又依赖于MqConfig呢,这两者导致了依赖循环 
-  
首先看下
rabbitTemplateConfigurer方法,从源码可以得知 参数里面需要一个ObjectProvider messageConverter消息转换器
 -  
我在
MqConfig里面 也自定义了一个消息转换器,问题就出在这里
 
造成error的原因
MqConfig依赖于rabbitTemplate
rabbitTemplate的自动注入需要有MessageConverter
而我又在MqConfig自定义了MessageConverter
MqConfig需要rabbitTemplate,由于我定义了消息转换器,而rabbitTemplate又会使用到MqConfig,
反反复复,就形成了循环依赖
解决
- 知道了错误的原因,解决起来就很简单了,就是因为 
MqConfig需要rabbitTemplate,由于我定义了消息转换器,而rabbitTemplate又会使用到MqConfig这个问题所导致循环依赖。 
第一种解决方案
-  
把消息转换器放到别的配置类中去,这样就可以避免
rabbitTemplate去找MqConfig
 
第二种解决方案
-  
要么就把
MqConfig类中的rabbitTemplate以及init方法拿走,直接切断关系使MqConfig不依赖于rabbitTemplate,我选择放在我的RabbitMqHelper类当中
 
测试
-  
完美启动,不报错了~

 
总结
依赖循环导致的问题,切断两者互相依赖关系即可~
- 编写有误还请大佬指正,万分感谢。
 



















