关于spring boot的Bean named ‘aaa‘ is expected to be of type ‘bbb‘ but was actually of type ‘bbb‘问题的解决方案

本文解析了在Spring Boot中因Bean名称重复导致的类型错误问题,提供了详细的解决方案,包括修改Bean名称和正确使用@Autowired与@Qualifier。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


  又是隔了几周没更新个人博客了,不行不行,自己必须坚持每周更新一篇博客。今天的博客同样是填一些开发过程所遇到的坑,下面开始今天的讲解。

  相信后端的同学在平时开发时都大多都使用到spring boot来开发,那么在使用bean工厂注册bean时说不定会遇到过Bean named 'aaa' is expected to be of type 'bbb' but was actually of type 'bbb'这个报错,那么这个问题到底是怎么引起的呢?如何解决呢?且听我慢慢讲解。

  有一天开发时突然收到上级发来的微信信息,他说他在我的项目中进行相关api测试时遇到了这样的问题叫我马上解决下,我发给大家看下。

在这里插入图片描述
  一看到是上级发来的信息,于是马上停下了手头上的工作,开始迅速分析并解决问题了。有些同学可能纳闷,这个报错描述得跟标题中的并不一样呀,是不是跑题了?其实仔细分析下,你会发现上级发的这个报错信息其实就是造成Bean named ‘aaa‘ is expected to be of type ‘bbb‘ but was actually of type ‘bbb‘这个报错的根本原因!从字面上可以知道两个不同包路径下都有RiskKnowledgeBuilder这个类,这两个RiskKnowledgeBuilder类在bean工厂中注册的bean的名称都为riskKnowledgeBuilder,所以就互相发生了冲突,进而导致了bean工厂在按照名称(byName)来装配RiskKnowledgeBuilder类到其它类时发现这个类所对应的bean的名称虽然也是riskKnowledgeBuilder,但bean的类型却是已经注册好的名称也为riskKnowledgeBuilder但却是不同类型(处于不同包路径下)的RiskKnowledgeBuilder类的报错。下面我贴出这两个不同包路径下的RiskKnowledgeBuilder类的截图,大家可以可以比较下。
路径1:
在这里插入图片描述

路径2:
在这里插入图片描述
  从上图我们不难看出这两个RiskKnowledgeBuilder类在bean工厂中注册的bean名称都为riskKnowledgeBuilder。既然找到原因并定位好问题所在,那么解决问题便不在话下了。那么怎么解决呢?其实很简单,两步搞定它!

1、 第一步,既然注册的bean名称重复了,那么我们可以修改其中一个RiskKnowledgeBuilder类所注册的bean的名称修改为riskKnowledgeBuilder1,如下所示:

@Component("riskKnowledgeBuilder1")
public class RiskKnowledgeBuilder  extends KnowledgeBuilder {

2.第二步,既然修改了该类注册的bean名称,那么我们在装配该类在其它类时,不能只单单使用@Autowired(按照类型来装配)和@Resource(按照名称来装配)这样的注解进行专配bean,因为这样的话spring都是默认将bean的名称设为的第一个字母小写这样的格式,比如上面的RiskKnowledgeBuilder如果用户不自己自定义的注册的bean名称的话,它在spring中默认的bean名称就是riskKnowledgeBuilder。所以我们可以两种方式进行改进:
第一种使用@Resource注解(按照名称来装配):

    @Resource(name = "riskKnowledgeBuilder1")
    private RiskKnowledgeBuilder riskKnowledgeBuilder;

第二种使用@Autowired注解(使其也按照名称来装配)*:

    @Autowired
    @Qualifier("riskKnowledgeBuilder1")
    private RiskKnowledgeBuilder riskKnowledgeBuilder;

  按照上面的步骤我很快就把该问题修复了,是不是很简单?写这篇博客时我也参考了另外一篇博客,那篇博客写得简明扼要,也是不错的,大家对我的解释如果还有疑惑的可以看下下面这篇博客。
Spring boot注入组件Bean named ‘XXX’ is expected to be of type ‘TTT’ but was actually of type ‘TTT’

  其实大多数人每次看到问题,不管三七二十一就来个疯狂的百度搜索、谷歌搜索的等等,只想先把问题解决再说,但这样虽然问题很快解决了,但你对问题的理解还不是很透彻。所以其实我们可以换个解决问题的思路。什么思路呢?很简单,也就是如下步骤:

  1. 分析产生这个问题的根本原因,找到导致这个报错出现的根源;
  2. 按照自己的理解多去尝试解决问题,多去试错;
  3. 自己多次尝试后依然解决不了,这时再去网上进行搜索或者寻求别人的帮助;
  4. 解决问题后找个时间进行思考总结,比如如何避免下次犯踩同样的坑,还有没有更好的方法等等。
### 解决 Spring Boot 中 `ddlApplicationRunner` Bean 类型不匹配问题 当遇到 `ddlApplicationRunner` bean 的类型不匹配错误时,通常是因为该 bean 实现了多个接口或继承了其他类,而容器尝试将其注入到特定类型的属性中。为了确保正确处理这个问题,可以采取以下措施: #### 1. 检查实现接口 确认 `ddlApplicationRunner` 是否实现了 `org.springframework.boot.ApplicationRunner` 或者 `CommandLineRunner` 接口之一。这两个接口都用于定义应用程序启动后的逻辑执行[^1]。 如果确实实现了上述任一接口,则应保证声明此 bean 的地方指定了正确的返回类型。例如,在配置文件中注册此类作为组件扫描的一部分时,应该让其自动识别并创建合适的实例。 ```java @Component public class DDLApplicationRunner implements ApplicationRunner { @Override public void run(ApplicationArguments args) throws Exception { // 执行DDL操作... } } ``` #### 2. 使用泛型限定符 有时即使实现了正确的接口也可能发生冲突,特别是在项目中有多个同名但不同包下的类的情况下。此时可以通过引入泛型来进一步指定期望的具体子类型,从而消除歧义[^2]。 对于这种情况,可以在依赖注入的地方显式地指出所需的参数化类型: ```java @Autowired private ApplicationRunner<YourSpecificType> ddlApplicationRunner; ``` 请注意这里的 `<YourSpecificType>` 应替换为你实际使用的具体业务对象类型名称。 #### 3. 调整Bean定义方式 另一种方法是在定义 `ddlApplicationRunner` 这个bean的时候直接指定它的全限定类名而不是仅仅通过接口来进行装配。这有助于防止因存在多重候选而导致的选择失败情况的发生[^3]。 ```java @Configuration public class AppConfig { @Bean(name="ddlApplicationRunner") public MyCustomApplicationRunner myCustomApplicationRunner(){ return new MyCustomApplicationRunner(); } } class MyCustomApplicationRunner implements ApplicationRunner{ ... } ``` 以上就是针对 `ddlApplicationRunner` bean 类型不匹配的一些解决方案建议。希望这些信息能够帮助解决问题所在的应用程序环境中的类似问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Melo_FengZhi

您的鼓励对我就是巨大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值