Spring注入bean发现多个候选bean错误


title: Spring注入bean发现多个候选bean错误
author: 红豆刨冰

1.问题描述

image-20240721175229698

报错信息

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 1 of constructor in com.hmall.trade.service.impl.OrderServiceImpl required a single bean, but 2 were found:
	- orderDetailServiceImpl: defined in file [/Users/tom/Desktop/SpringCloud微服务—资料/day03-微服务01/资料/hmall/trade-service/target/classes/com/hmall/trade/service/impl/OrderDetailServiceImpl.class]
	- IOrderDetailService: defined in file [/Users/tom/Desktop/SpringCloud微服务—资料/day03-微服务01/资料/hmall/trade-service/target/classes/com/hmall/trade/service/IOrderDetailService.class]

这个错误信息表明在 Spring 容器中有两个候选的 Bean 满足 OrderController 的构造函数参数要求,而 Spring 无法确定应该注入哪一个。这两个候选的 Bean 是 orderServiceImpl 和 IOrderService。

2.解决方法

在 Spring 依赖注入过程中,OrderDetailServiceImpl 类是 IOrderDetailService 接口的一个实现类,当使用接口类型(IOrderDetailService)进行注入时,Spring 容器中可能有多个该接口的实现类,而 Spring 无法自动决定使用哪一个实现类,所以会报错

解决方法有三种,推荐前两种

方法一:使用 @Qualifier 注解

在 OrderController 中使用 @Qualifier 注解明确指定要注入的实现类

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final ItemClient itemClient;
//    private final OrderDetailServiceImpl detailService;
    private final IOrderDetailService detailService;
    private final CartClient cartClient;

    public OrderServiceImpl(ItemClient itemClient, @Qualifier("orderDetailServiceImpl") IOrderDetailService orderDetailService, CartClient cartClient) {
        this.itemClient = itemClient;
        this.detailService = orderDetailService;
        this.cartClient = cartClient;
    }
  //...
}

方法二:使用 @Primary 注解

在 OrderServiceImpl 类上添加 @Primary 注解,指定它为默认实现。

@Primary
@Service
public class OrderDetailServiceImpl extends ServiceImpl<OrderDetailMapper, OrderDetail> implements IOrderDetailService {

}

方法三:直接使用实现类创建(不推荐)

@Service
@RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    private final ItemClient itemClient;
    private final OrderDetailServiceImpl detailService;
//    private final IOrderDetailService detailService;
    private final CartClient cartClient;
  //...
}

直接找到该具体类型的 Bean 并注入,不会有歧义,所以不会报错.

虽然直接注入具体实现类可以解决问题,但从设计上考虑,通常推荐依赖接口而不是具体实现类。

3.疑问

为何一个接口一个实现类也会报错,黑马视频里就没有报错???

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值