@Primary是Spring解决同类型多个Bean注入歧义的默认选择机制:当接口有多个实现类且未用@Qualifier指定时,Spring自动注入被@Primary标记的唯一实现类。

@Primary 是 Spring 解决“同类型多个 Bean”注入歧义最直接的方式:当接口有多个实现类,又没用 @Qualifier 显式指定时,Spring 会自动选择被 @Primary 标记的那个 Bean 进行注入。
什么时候必须加 @Primary
只要满足这两个条件,就可能出现注入失败(NoUniqueBeanDefinitionException):
- 定义了一个接口(如
NotificationService) - 该接口至少有两个
@Service或@Component实现类注册进 Spring 容器
此时,若在其他类中写 @Autowired private NotificationService service;,Spring 不知道选哪个——加 @Primary 就是给它一个明确的默认答案。
@Primary 的正确写法
它必须标注在具体实现类(或 @Bean 方法)上,不能标在接口或抽象类上。常见组合如下:
-
@Service @Primary—— 用于普通服务实现类 -
@Repository @Primary—— 用于数据访问层主实现 -
@Bean @Primary—— 用于配置类中手动定义的 Bean
例如:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@Service @Primary
public class EmailNotificationService implements NotificationService { ... }
@Service
public class SmsNotificationService implements NotificationService { ... }
这样,所有未指定 @Qualifier 的 @Autowired NotificationService 都会注入 EmailNotificationService。
@Primary 和 @Qualifier 的关系
@Qualifier 优先级永远高于 @Primary,二者可共存,互不干扰:
- 不写
@Qualifier→ 按@Primary选默认 Bean - 写了
@Qualifier("smsNotificationService")→ 即使它没加@Primary,也强制注入该 Bean - 同一个接口下,只能有一个类加
@Primary,否则启动报错
它对各种注入方式都生效
无论你用哪种方式注入依赖,@Primary 都起作用:
- 字段注入:
@Autowired private PaymentService service; - 构造器注入(推荐):
public OrderService(@Autowired PaymentService service) - Setter 注入:
@Autowired public void setPaymentService(PaymentService service)
注意:@Primary 不影响 Bean 创建顺序,也不控制运行时动态切换;它只在依赖解析阶段起“默认候选”作用。

















