spring @primary注解

本文通过实例解析了Spring框架中@Primary注解的作用,当存在多个相同类型的Bean时,该注解用于指定默认注入的Bean,避免了NoUniqueBeanDefinitionException异常。通过对比OperaSinger和MetalSinger两个Singer接口实现类,阐述了如何使用@Primary注解解决依赖注入冲突。

spring中少见的注解@primary注解,例子

文章引自:http://jackyrong.iteye.com/blog/2208000
@Component
public class MetalSinger implements Singer{

@Override  
public String sing(String lyrics) {  
    return "I am singing with DIO voice: "+lyrics;  
}  

}

public class OperaSinger implements Singer {
@Override
public String sing(String lyrics) {
return "I am singing in Bocelli voice: "+lyrics;
}
}

这两个类都实现了singer接口

public interface Singer {
String sing(String lyrics);
}

那么来个注入的:

@Component
public class SingerService {
private static final Logger logger = LoggerFactory.getLogger(SingerService.class);

@Autowired  
private Singer singer;  

public String sing(){  
    return singer.sing("song lyrics");  
}  

}

那么最后输出应该是:I am singing with DIO voice: song lyrics.

原因是只有MetalSinger使用了注解@component,那么autowird会只寻找这个标记的
进行注入:
如果也在OperaSinger 中使用了注解,则spring会报异常,不知道到底应该用
哪个:
org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [main.service.Singer] is defined: expected single matching bean but found 2: metalSinger,operaSinger
而如果要让spring知道必须注入的是OperaSinger ,则可以用@primary注解告诉
spring:

@Primary
@Component
public class OperaSinger implements Singer{

@Override  
public String sing(String lyrics) {  
    return "I am singing in Bocelli voice: "+lyrics;  
}  

}

`@Primary`是Spring依赖注入中解决多Bean冲突的轻量级工具,用于解决依赖注入时的选择冲突,通过标记默认实现简化配置逻辑,其核心价值在于降低代码复杂度与提升可维护性,适用于需要统一默认行为的场景[^2]。 在Spring框架中,当存在多个同类型的Bean可供注入时,Spring默认会抛出异常。使用`@Primary`注解,可以指示Spring在遇到多个候选Bean时优先选择标记了该注解的Bean。其主要特点包括解决多个相同类型Bean的注入冲突,适用于全局范围,默认优先选择被标记为`@Primary`的Bean,还可以与`@Qualifier`配合使用,满足更复杂的注入需求[^1]。 ### 应用场景 - **多个实现**:当一个接口有多个实现类时,如果想要默认注入某一个实现,可以使用`@Primary`。 - **不同配置环境**:在多种配置环境下,有时需要优先使用某个特定的Bean,比如在测试环境和生产环境中可能会有不同的实现。 - **避免显式指定**:如果不希望在每次注入时都显式指定Bean的名称,可以使用`@Primary`来简化代码[^3]。 ### 示例代码 ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; // 定义一个接口 interface MyService { void doSomething(); } // 实现类1 class MyServiceImpl1 implements MyService { @Override public void doSomething() { System.out.println("MyServiceImpl1 is doing something."); } } // 实现类2,标记为 @Primary @Primary class MyServiceImpl2 implements MyService { @Override public void doSomething() { System.out.println("MyServiceImpl2 is doing something."); } } // 配置类 @Configuration class AppConfig { @Bean MyService myService1() { return new MyServiceImpl1(); } @Bean @Primary MyService myService2() { return new MyServiceImpl2(); } } ``` 在上述示例中,当进行依赖注入时,如果没有显式指定要注入的Bean名称,Spring会优先选择标记了`@Primary`注解的`MyServiceImpl2`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值