Spring中@Primary注解的作用及小demo演示
一、@Primary注解的核心作用
@Primary是Spring框架中用于解决依赖注入歧义问题的注解,当容器中存在多个相同类型的Bean时,Spring无法自动决定注入哪一个,此时通过@Primary标记某个Bean为“首选”,注入时会优先选择该Bean。其核心价值在于简化默认Bean的选择逻辑,避免在每个注入点都使用@Qualifier显式指定。
二、@Primary的典型使用场景
-
多实现类冲突:一个接口有多个实现类(如
UserService有UserServiceImplA和UserServiceImplB),希望默认注入其中一个; -
多数据源配置:项目中需要连接多个数据库(如MySQL和PostgreSQL),设置其中一个为默认数据源;
-
第三方库集成:避免第三方库的Bean与自定义Bean冲突,通过
@Primary指定优先使用的实现。
三、小demo演示(接口多实现场景)
1. 定义接口与实现类
假设我们有一个MessageService接口,用于发送消息,有两个实现类:EmailMessageService(发送邮件)和SmsMessageService(发送短信)。
// 接口定义
public interface MessageService {
void sendMessage(String content);
}
// 邮件服务实现(默认首选)
@Component
@Primary
public class EmailMessageService implements MessageService {
@Override
public void sendMessage(String content) {
System.out.println("【邮件】发送消息:" + content);
}
}
// 短信服务实现
@Component
public class SmsMessageService implements MessageService {
@Override
public void sendMessage(String content) {
System.out.println("【短信】发送消息:" + content);
}
}
2. 注入并使用接口
创建一个MessageController,通过构造器注入MessageService,无需指定具体实现:
@Component
public class MessageController {
private final MessageService messageService;
@Autowired
public MessageController(MessageService messageService) {
this.messageService = messageService;
}
public void send() {
messageService.sendMessage("Hello, Spring @Primary!");
}
}
3. 运行结果
启动Spring应用(如通过AnnotationConfigApplicationContext加载配置),调用MessageController.send()方法,输出结果为:
【邮件】发送消息:Hello, Spring @Primary!
原因:EmailMessageService被标记为@Primary,Spring在注入MessageService时优先选择了它。若移除@Primary注解,Spring会抛出NoUniqueBeanDefinitionException(多个相同类型Bean无法确定注入哪一个)。
四、关键说明
-
与@Qualifier的区别:
@Primary是全局默认选择(适用于所有注入点),而@Qualifier是局部显式指定(需在注入时明确指定Bean名称,如@Qualifier("smsMessageService")); -
配置类中使用:若Bean通过
@Bean方法手动创建,同样可以在方法上添加@Primary(如@Bean @Primary public MessageService emailMessageService())。
通过这个小demo,可以清晰看到@Primary如何解决多Bean注入的歧义问题,简化默认Bean的选择流程。
浙公网安备 33010602011771号