The dependencies of some of the beans in the application context form a cycle

你们好,我是金金金。

image.png

场景

在这里插入图片描述

  • 启动服务时,报错:应用程序上下文中的某些bean的依赖关系形成了一个循环

循环依赖

依赖循环指的是两个或多个类之间相互依赖的情况,即类A依赖类B,同时类B也依赖类A。 这种情况会导致编译器无法确定类的加载顺序,从而产生编译错误

在这里插入图片描述

  • 如上图:BeanA 类依赖了 BeanB 类,同时 BeanB 类又依赖了 BeanA 类。这种依赖关系形成了一个闭环,这种依赖关系就称之为循环依赖

排查

从报错信息可以得知,这是一个依赖循环的问题~,问题出在MqConfigrabbitTemplateConfigurer这两者形成了相互依赖,从而产生了依赖循环

  • 从报错得知,整理的依赖顺序如下~

    payController 依赖于 payOrderServiceImpl

    payOrderServiceImpl 依赖于 MqConfig

    MqConfig 依赖于 rabbitTemplate

    rabbitTemplate 依赖于 rabbitTemplateConfigurer

    rabbitTemplateConfigurer 依赖于 MqConfig
  • 好,一步步来,走起~
  1. 我先贴出MqConfigRabbitMqHelper代码

    Mq.config.java
    在这里插入图片描述

    RabbitMqHelper.java
    在这里插入图片描述

  2. 从报错开始排查,首先看PayController,这里面使用了IPayOrderService那必然有依赖关系

    在这里插入图片描述

  3. 再继续看payOrderServiceImpl

    在这里插入图片描述

    • PayOrderServiceImpl里面使用到了rabbitMqHelper,而rabbitMqHelper又是在MqConfig里面注册为一个Bean的,所以也就是为什么payOrderServiceImpl依赖于MqConfig的原因了~
  4. 继续走,我们看一下MqConfig,其实上面也有贴出MqConfig的详细代码了,我这里再放一遍

    在这里插入图片描述

    • 从报错显示,MqConfig依赖于rabbitTemplate,这很明显了,因为我MqConfig里面有使用到rabbitTemplate,所以也存在着依赖关系
  5. 继续,我们可以看到rabbitTemplate依赖于rabbitTemplateConfigurer,这里得看一下源码了,跟着节奏,走起

    • 我们来到RabbitAutoConfiguration 里面,可以看到三个内部类

      在这里插入图片描述

    • 根据报错得知rabbitTemplate依赖于rabbitTemplateConfigurer,来看下RabbitTemplateConfiguration这个内部类究竟是什么?

      在这里插入图片描述

      • 现在就很明显了,可以看到rabbitTemplate就在RabbitTemplateConfiguration内部类当中,rabbitTemplate在这个内部类当中注册为了Bean,而且这个Bean是依赖于RabbitTemplateConfigurer的,所以也就是为什么rabbitTemplate依赖于rabbitTemplateConfigurer
  6. 好,现在也就是最后一点,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类当中

    在这里插入图片描述

测试

  • 完美启动,不报错了~

    在这里插入图片描述

总结

依赖循环导致的问题,切断两者互相依赖关系即可~

  • 编写有误还请大佬指正,万分感谢。
  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值