容器中同一接口多个实现类

当 Spring 容器中存在同一接口的多个实现类时,有哪些方式可以决定某个场景调用哪个实现?

Spring 默认按类型注入会报 NoUniqueBeanDefinitionException。下面按使用频率和适用场景,梳理常见的解决方式。

  1. @Primary:指定默认首选
    在某个实现类上加@Primary,当注入点没有其他限定信息时,优先选它
java 复制代码
public interface PayService {
    void pay();
}

@Service
@Primary
public class AlipayService implements PayService { ... }

@Service
public class WechatPayService implements PayService { ... }

@Service
public class OrderService {
    @Autowired
    private PayService payService; // 注入 AlipayService
}

适用于有一个明确默认实现,少数场景才用其他实现

  1. @Qualifier:按Bean名称精确指定
    配合 @Autowired 使用,指定要注入的 Bean 名称(默认是类名首字母小写)。
java 复制代码
@Service
public class OrderService {
    @Autowired
    @Qualifier("wechatPayService")
    private PayService payService;
}
  1. 按字段名/参数名匹配
    Spring在按类型找到多个候选后,会退一步用注入点的名称去匹配Bean名称
java 复制代码
@Service
public class OrderService {
    @Autowired
    private PayService wechatPayService; // 字段名匹配 Bean 名,注入 WechatPayService
}
  1. 注入集合或Map:拿到全部实现
java 复制代码
@Service
public class PayFactory {
    // 注入所有实现
    @Autowired
    private List<PayService> services;

    // key 是 Bean 名称,value 是实现
    @Autowired
    private Map<String, PayService> serviceMap;

    public PayService get(String name) {
        return serviceMap.get(name);
    }
}

这是策略模式 + 工厂的经典写法,配合Map可以做到按名称路由。

还有其他方式等。

相关推荐
小楊不秃头4 个月前
Spring:Bean的存储
java·spring·bean
tongluowan0075 个月前
@Autowired 和 @Resource 有什么区别?
java·spring·bean
庞轩px5 个月前
第七篇:Spring扩展点——如何优雅地介入Bean的创建流程
java·后端·spring·bean·aware·扩展点
庞轩px5 个月前
第六篇:Spring用了哪些设计模式?——从单例到代理,拆解框架中的经典设计
java·spring·设计模式·bean·代理模式·aop·单例
阿维的博客日记5 个月前
容器是怎么管理 Bean 的?
java·bean
小同志006 个月前
⽅法注解 @Bean
java·spring·bean·maven
callJJ8 个月前
Spring Bean 生命周期详解——从出生到销毁,结合源码全程追踪
java·后端·spring·bean·八股文
Elias不吃糖8 个月前
Spring Bean 注入与容器管理:从“怎么交给容器”到“怎么被注入使用”的完整总结
java·spring·rpc·bean
az31310 个月前
Spring Bean初始化机制详解
java·spring·bean·初始化