Spring @Qualifier 的使用,以及与 @Primary 的关系

通过本篇,你将学到:@Qualifier 的使用方法, 以及和 @Primary 的关系。

一、概述

Qualifier 英文解释中,包含合格者、限定者的意思。透过含义,我们也可以大致的判断出@Qualifier注解,和过滤和筛选有关。

果不其然,@Qualifier 注解就是为了消除歧义(当Spring无法判断出哪个bean应该被注入时),限制bean的注入,指定我们需要注入的类。

使用 @Autowired 注解是 Spring 依赖注入的绝好方法,这也是我们在业务中经常使用的注解,但是有些场景下仅仅靠这个注解不足以让Spring知道到底要注入哪个 bean。如果容器中有多个相同类型的 bean,则框架将抛出异常 - “NoUniqueBeanDefinitionException”, 以提示有多个满足条件的 bean 进行自动装配。

程序无法正确做出判断使用哪一个 bean,下面就是个鲜活的例子:

public interface Formatter {
    String format();
}

@Component("firstFormatter")
public class FirstFormatter implements Formatter {
    @Override
    public String format() {
        return "first";
    }
}

@Component("secondFormatter")
public class SecondFormatter implements Formatter {
    @Override
    public String format() {
        return "second";
    }
}

当我们在 Rest 层注入 Formatter 服务时,由于存在两个实现类,导致“不唯一bean”的错误,IDEA编译器也会提醒并提示我们解决办法。

Spring @Qualifier 的使用,以及与 @Primary 的关系_第1张图片

二、@Qualifie

在依赖注入时,因为@Autowired 注解是by type的,当类型存在相同时,使用@Qualifier 注解可以消除歧义,如下:

@SpringBootTest
class QualifierTest {
    @Qualifier("firstFormatter")
    @Autowired
    private Formatter formatter;
    @Test
    void test() {
        System.out.println(formatter.format());    // 输出:first
    }
}

@Qualifier 注解的作用,就是指定我们注入的是哪个类,防止抛出“不唯一bean”的异常。

注意:@Qualifier()后面带的参数名称,必须为我们之前定义@Service注解的名称之一,不能无中生有

三、@Paimary

还有另一个名为 @Primary 的注解。当存在多个相同类型的 bean 时,此注解定义了首选项,除非另有说明,否则将使用与 @Primary 注释关联的 bean 。

public interface Formatter {
    String format();
}

@Primary 
@Component("firstFormatter")
public class FirstFormatter implements Formatter {
    @Override
    public String format() {
        return "first";
    }
}

@Component("secondFormatter")
public class SecondFormatter implements Formatter {
    @Override
    public String format() {
        return "second";
    }
}

值得注意的是:如果 @Qualifier 和 @Primary 注释都存在,那么 @Qualifier 注释将具有优先权。因为 @Primary 定义的只是默认值,而 @Qualifier 则非常具体的指定了哪一个。

四、其他

除此之外,我们也可以通过名称来实现自动注入,这与使用 @Qualifier 注解指定类的原理相同,如下:

@SpringBootTest
class QualifierTest {
    @Autowired
    private Formatter firstFormatter;
    @Test
    void test() {
        System.out.println(formatter.format());    // 输出:first
    }
}

五、总结

  • @Qualifier 注解是用来消除依赖注入冲突的;
  • @Primary 注解可以定义默认注入的类;
  • 该注解在 MQ 的使用中较常见,如:RabbitMQ 的队列声明...

少侠请留步 ... ヾ(◍°∇°◍)ノ゙ ... 
欢迎点赞、评论、加关注,让更多人看到学到赚到
更多精彩,请关注我的"今日头条号":Java云笔记

你可能感兴趣的:(#,《Spring,全家桶》,Qualifier,spring,Autowired,Resource,Primary)