• Spring 注解 @Qualifier 详解


    目录

    1. 概述

    2. 痛点

    3. @Qualifier

    4. @Qualifier VS @Primary

    5. 通过名称来自动注入


    1. 概述

    今天带你了解一下 Spring 框架中的 @Qualifier 注解,它解决了哪些问题,以及如何使用它。我们还将了解它与 @Primary 注解的不同之处。更多的技术解析请访问 felord.cn

    2. 痛点

    使用 @Autowired 注解是 Spring 依赖注入的绝好方法。但是有些场景下仅仅靠这个注解不足以让Spring知道到底要注入哪个 bean
    默认情况下,@Autowired 按类型装配 Spring Bean
    如果容器中有多个相同类型的 bean,则框架将抛出 NoUniqueBeanDefinitionException, 以提示有多个满足条件的 bean 进行自动装配。程序无法正确做出判断使用哪一个,下面就是个鲜活的例子:

    1. @Component("fooFormatter")
    2. public class FooFormatter implements Formatter {
    3. public String format() {
    4. return "foo";
    5. }
    6. }
    7. @Component("barFormatter")
    8. public class BarFormatter implements Formatter {
    9. public String format() {
    10. return "bar";
    11. }
    12. }
    13. @Component
    14. public class FooService {
    15. @Autowired
    16. private Formatter formatter;
    17. //todo
    18. }

    如果我们尝试将 FooService 加载到我们的上下文中,Spring 框架将抛出 NoUniqueBeanDefinitionException。这是因为 Spring 不知道要注入哪个 bean。为了避免这个问题,有几种解决方案。那么我们本文要讲解的 @Qualifier 注解就是其中之一。跟着小胖哥的节奏往下走。

    3. @Qualifier

    通过使用 @Qualifier 注解,我们可以消除需要注入哪个 bean 的问题。让我们重新回顾一下前面的例子,看看我们如何通过包含 @Qualifier 注释来指出我们想要使用哪个 bean 来解决问题:

    1. @Component
    2. public class FooService {
    3. @Autowired
    4. @Qualifier("fooFormatter")
    5. private Formatter formatter;
    6. //todo
    7. }

    通过将 @Qualifier 注解与我们想要使用的特定 Spring bean 的名称一起进行装配,Spring 框架就能从多个相同类型并满足装配要求的 bean 中找到我们想要的,避免让Spring脑裂。我们需要做的是@Component或者@Bean注解中声明的value属性以确定名称。
    其实我们也可以在 Formatter 实现类上使用 @Qualifier 注释,而不是在 @Component 或者 @Bean 中指定名称,也能达到相同的效果:

    1. @Component
    2. @Qualifier("fooFormatter")
    3. public class FooFormatter implements Formatter {
    4. public String format() {
    5. return "foo";
    6. }
    7. }
    8. @Component
    9. @Qualifier("barFormatter")
    10. public class BarFormatter implements Formatter {
    11. public String format() {
    12. return "bar";
    13. }
    14. }

    4. @Qualifier VS @Primary

    还有另一个名为 @Primary 的注解,我们也可以用来发生依赖注入的歧义时决定要注入哪个 bean。当存在多个相同类型的 bean 时,此注解定义了首选项。除非另有说明,否则将使用与 @Primary 注释关联的 bean 。
    我们来看一个例子:

    1. @Bean
    2. public Employee tomEmployee() {
    3. return new Employee("Tom");
    4. }
    5. @Bean
    6. @Primary
    7. public Employee johnEmployee() {
    8. return new Employee("john");
    9. }

    在此示例中,两个方法都返回相同的 Employee类型。Spring 将注入的 bean 是方法 johnEmployee 返回的 bean。这是因为它包含 @Primary 注解。当我们想要指定默认情况下应该注入特定类型的 bean 时,此注解很有用。
    如果我们在某个注入点需要另一个 bean,我们需要专门指出它。我们可以通过 @Qualifier 注解来做到这一点。例如,我们可以通过使用 @Qualifier 注释来指定我们想要使用 tomEmployee 方法返回的 bean 。
    值得注意的是,如果 @Qualifier 和 @Primary 注释都存在,那么 @Qualifier 注释将具有优先权。基本上,@Primary 是定义了默认值,而 @Qualifier 则非常具体。
    当然@Component 也可以使用@Primary 注解,这次使用的还是上面3的示例:

    1. @Component
    2. @Primary
    3. public class FooFormatter implements Formatter {
    4. public String format() {
    5. return "foo";
    6. }
    7. }
    8. @Component
    9. public class BarFormatter implements Formatter {
    10. public String format() {
    11. return "bar";
    12. }
    13. }

    在这种情况下,@Primary 注解指定了默认注入的是 FooFormatter,消除了场景中的注入歧义。

    5. 通过名称来自动注入

    在使用 @Autowired 进行自动装配时,如果 Spring 没有其他提示,将会按照需要注入的变量名称来寻找合适的 bean。也可以解决依赖注入歧义的问题。让我们看一些基于我们最初的例子的代码:

    1. @Component
    2. public class FooService {
    3. @Autowired
    4. private Formatter fooFormatter;
    5. //todo
    6. }

    在这种情况下,Spring 将确定要注入的 bean 是 FooFormatter,因为字段名称与我们在该 bean 的 @Component或者 @Bean 注解中使用的值(默认 @Bean 使用方法名)相匹配。

  • 相关阅读:
    数据库错误知识集3(摘)
    Linux 命令行——网络系统、ping、netstat、ftp、wget、ssh
    多线程---synchronized特性+原理
    车规级MCU进入「新周期」,中国本土供应商竞逐竞争力TOP10
    网络安全领域必备工具,其中一个绝了
    如何通过MES系统提高生产计划效率?
    Overleaf论文排版踩坑记录
    详解Web应用安全系列(1)注入漏洞之SQL注入
    Vue3+typescript项目使用script-setup写法时,模版中的变量和方法编辑器检测都为Unresolved variable或者Element is not exported,如何解决
    vue3 的动态路由 以及history模式
  • 原文地址:https://blog.csdn.net/leesinbad/article/details/128535877