spring @Primary-在spring中的使用

在spring 中使用注解,常使用@Autowired, 默认是根据类型Type来自动注入的。但有些特殊情况,对同一个接口,可能会有几种不同的实现类,而默认只会采取其中一种的情况下 @Primary 的作用就出来了。下面是个简单的使用例子。

有如下一个接口

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

有下面的两个实现类:

@Component // 加注解,让spring识别
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;
    }
}

下面就是注入上面的

@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. 原因很简单,就是 OperaSinger 这个类上面根本没有加上注解@Copmonent 或者 @Service, 所以spring 注入的时候,只能找到 MetalSinger 这个实现类. 所以才有这个结果。

但是如果一旦 OperaSinger 这个类加上了@Copmonent 或者 @Service 注解,有趣的事情就会发生,你会发现一个错误的结果或异常: 
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 根据类型无法选择到底注入哪一个。这个时候@Primay 可以闪亮登场了。

@Primary
@Component
public class OperaSinger implements Singer{

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

如果代码改成这样,再次运行,结果如下: 
“I am singing in Bocelli voice: song lyrics”, 用@Primary 告诉spring 在犹豫的时候优先选择哪一个具体的实现。

二、用@Qualifier这个注解来解决问题

将上面的两个类改为如下:

@Component // 加注解,让spring识别
@Qualifier("metalSinger")
public class MetalSinger implements Singer{

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

@Component
@Qualifier("opreaSinger")
public class OperaSinger implements Singer {
    @Override
    public String sing(String lyrics) {
        return "I am singing in Bocelli voice: "+lyrics;
    }
}
@Component
public class SingerService {
    private static final Logger logger = LoggerFactory.getLogger(SingerService.class);

    @Autowired
    private Singer singer;

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

扩展:Spring注解常用汇总

使用注解之前要开启自动扫描功能

其中base-package为需要扫描的包(含子包)


@Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean。 
@Scope注解 作用域 
@Lazy(true) 表示延迟初始化 
@Service用于标注业务层组件、 
@Controller用于标注控制层组件(如struts中的action) 
@Repository用于标注数据访问组件,即DAO组件。 
@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。 
@Scope用于指定scope作用域的(用在类上) 
@PostConstruct用于指定初始化方法(用在方法上) 
@PreDestory用于指定销毁方法(用在方法上) 
@Resource 默认按名称装配,当找不到与名称匹配的bean才会按类型装配。 
@DependsOn:定义Bean初始化及销毁时的顺序 
@Primary:自动装配时当出现多个Bean候选者时,被注解为@Primary的Bean将作为首选者,否则将抛出异常 
@Autowired 默认按类型装配,如果我们想使用按名称装配,可以结合@Qualifier注解一起使用 
@Autowired @Qualifier(“personDaoBean”) 存在多个实例配合使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spring的@Primary和@Qualifier是两个常用的注解,用于解决当有多个同类型的bean需要注入时的歧义问题。 @Primary注解用在bean的定义上,表示该bean是优先选择的bean。当有多个同类型的bean需要注入时,Spring会优先选择被@Primary注解标记的bean作为注入的对象。 @Qualifier注解用在注入点上,可以和@Autowired、@Resource等注解一起使用,用来指定具体要注入的bean的名称。通过在@Qualifier指定bean的名称,可以明确告诉Spring要选择哪个bean进行注入。 举个例子来说明,假设有一个接口类型的bean,下面有两个实现类A和B都实现了这个接口,并且都被Spring管理。 当我们在其他地方需要注入这个接口类型的bean时,如果不使用@Qualifier和@Primary,Spring会产生歧义,无法确定注入哪个实现类的对象。 使用@Primary注解,我们可以在实现类A上标注@Primary,表示A是优先选择的bean。 当需要注入接口类型bean时,Spring会自动选择A作为注入的对象。 使用@Qualifier注解,我们可以在注入点上标注@Qualifier,然后在@Qualifier指定具体要注入的bean的名称。 比如,可以使用@Qualifier("beanA")明确指定要注入的bean是A。 以上就是@Primary和@Qualifier的基本用法和含义,通过使用这两个注解可以很方便地解决多个同类型bean的注入问题。 ### 回答2: spring的@Primary和@Qualifier是依赖注入的两个注解。 @Primary注解用于标注一个类为首选的bean。当有多个类型相同的bean存在时,spring将会优先选择被@Primary注解标注的bean进行注入。 @Qualifier注解可以与@Autowired一起使用,用于解决存在多个类型相同的bean时的歧义性。通过为@Autowired指定@Qualifier注解的value属性,可以指定具体注入哪个bean。 例如,假设我们有一个接口Person,有两个实现类:Student和Teacher。如果我们在Spring配置文件同时注册了这两个bean,那么在注入Person类型的依赖时就会有歧义。此时,我们可以使用@Primary注解为其一个实现类标注为首选bean。这样,在需要注入Person类型的地方,spring就会优先选择被@Primary注解标注的实现类进行注入。 另一种情况是,如果我们不想使用@Primary注解来标注首选bean,而是希望根据特定的条件进行选择注入,就可以使用@Qualifier注解。@Qualifier注解需要与@Autowired注解一起使用,通过指定value属性来指定注入哪个bean。比如,我们可以在@Autowired注解后添加@Qualifier("student")来指定注入的是Student类型的bean。 通过@Primary和@Qualifier注解,我们可以在存在多个类型相同的bean时,精确控制注入的对象,避免歧义性。 ### 回答3: Spring是一个开源的Java框架,提供了依赖注入(Dependency Injection)的功能。在Spring,我们可以使用@Primary和@Qualifier注解来处理多个相同类型的实例。 @Primary注解用于标识在多个相同类型的Bean,哪个Bean应该作为首选的Bean。当我们不使用@Qualifier注解指定具体的Bean时,Spring会自动选择使用带有@Primary注解的Bean。例如,当我们有多个实现了同一个接口的类时,通过使用@Primary注解,我们可以指定一个类作为主要实现。 @Qualifier注解用于在多个相同类型的Bean选择特定的Bean。当我们有多个相同类型的Bean需要注入时,在使用@Autowired或@Inject注入时,我们可以使用@Qualifier注解指定具体的Bean。@Qualifier注解的参数可以是Bean的名字或者是自定义的标识符。 举个例子来说,假设我们有一个接口Animal,有两个实现类Dog和Cat。如果我们希望将Cat作为首选的实现类,我们可以在Cat类上使用@Primary注解。如果有一个需要注入Animal类型的类,但我们想注入Dog,我们可以在注入的地方使用@Qualifier("dog")注解来指定具体的Bean。 总之,@Primary注解用于标识首选的Bean,@Qualifier注解用于指定特定的Bean。它们可以一起使用来处理多个相同类型的实例,使得依赖注入更加灵活和精确。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值