【问题标题】:When to use Qualifier and Primary in Spring什么时候在 Spring 中使用 Qualifier 和 Primary
【发布时间】:2019-06-18 05:38:13
【问题描述】:

我读过@Qualifier 可以用于注入阶段,而@Primary 用于配置阶段。我还不清楚什么时候用哪个。

我也有以下疑问

  • @Primary 和@Qualifier 可以一起使用吗?如果是,@Qualifier 是否优先?

  • @Primary 可以与@Autowired 一起使用吗?

  • 注入阶段与配置阶段有何不同,这与 Spring bean 相关

【问题讨论】:

    标签: spring annotations


    【解决方案1】:

    @Primary 表示当有多个候选者时,应该优先考虑一个bean 有资格自动装配单值依赖项。

    @Qualifier 表示当有多个候选者时,应该自动装配特定的 bean。

    例如,我们有两个 bean 都实现了相同的接口。

    public interface BeanInterface {
    
        String getName();
    }
    
    
    public class Bean1 implements BeanInterface {
        @Override
        public String getName() {
            return "bean 1";
        }
    }
    
    
    public class Bean2 implements BeanInterface {
        @Override
        public String getName() {
            return "bean2";
        }
    }
    

    这是我们的服务。

    @Service
    public class BeanService {
    
        @Autowired
        private BeanInterface bean;
    }
    

    还有我们的配置。

    @Configuration
    public class Config {
    
        @Bean("bean1")
        public BeanInterface bean1() {
            return new Bean1();
        }
    
        @Bean("bean2")
        public BeanInterface bean2() {
            return new Bean2();
        }
    }
    

    当Spring启动时,它会发现有两个bean(“bean1”和“bean2”)都可以自动连接到BeanService,因为它们实现了相同的接口BeanInterface。它在我的想法中报告错误。

    Could not autowire. There is more than one bean of 'BeanInterface' type.
    Beans: bean1   (Config.java) 
    bean2   (Config.java) 
    

    而且没有提示,Spring 不知道该使用哪一个。

    所以在我们的例子中,当我们将@Primary 添加到Config.bean1() 时。

    @Bean("bean1")
    @Primary
    public BeanInterface bean1() {
        return new Bean1();
    }
    

    它告诉 Spring,“当您发现多个 bean 都可以自动装配时,请使用 primary one 作为您的第一个选择。”因此,Spring 将选择 bean1 自动连接到 BeanService

    这是在BeanService.class 中使用@Qualifierbean1 自动连接到BeanService 的另一种方法。

    @Service
    public class BeanService {
    
        @Autowired
        @Qualifier("bean1")
        private BeanInterface bean;
    }
    

    @Qualifier 会告诉 Spring,“无论你找到多少豆子,只要使用我告诉你的那个。

    所以你可以发现@Qualifier@Primary 都在告诉 Spring 在多个候选人有资格自动装配时使用特定的 bean。但@Qualifier 更具体,优先级更高。所以当@Qualifier@Primary都被找到时,@Primary会被忽略。

    这是测试。

    @Configuration
    public class Config {
    
        @Bean("bean1")
        @Primary
        public BeanInterface bean1() {
            return new Bean1();
        }
    
        @Bean("bean2")
        public BeanInterface bean2() {
            return new Bean2();
        }
    }
    
    @Service
    public class BeanService {
    
        @Autowired
        @Qualifier("bean2")
        private BeanInterface bean;
    
        @PostConstruct
        public void test() {
            String name = bean.getName();
            System.out.println(name);
        }
    }
    

    输出是“bean2”。

    【讨论】:

    • 哇,你已经清除了我所有的疑虑..非常感谢您提供的清晰示例!与 XML 相比,我们使用基于注释的配置的频率如何?基于 xml 的配置比编程更好还是得分?
    • 使用java配置是一种趋势,因为程序化配置更加方便和清晰。
    • 您不必用@Component 标记类定义,因为您已经用@Bean 注释了配置类中的方法名称,在这种情况下就足够了。不过答案很好!
    • @securecurve 是的,你是对的。我已经修改过了,谢谢指出。
    【解决方案2】:

    另外,需要记住@Qualifier 的优先级高于@Primary,这意味着定义两个注解是浪费的。

    @Primary是默认实现,@Qualifier是具体实现。

    您可以查看我写的关于此注释的博客 - http://shaikezam.com/spring_qualifier

    【讨论】:

    • 请在上面的帖子中添加一个引用,以防将来链接失效。
    【解决方案3】:

    是的,@Qualifier 优先。 是的,我们可以同时使用@Primary 和@Autowired。

    @Configuration 与应用程序上下文相关的类,可用于配置应用程序级别的配置。

    【讨论】:

      【解决方案4】:

      要访问具有相同类型的bean,我们通常使用@Qualifier(“beanName”) 注解。我们将它与@Autowired 一起应用在注入点。在我们的例子中,我们在配置阶段选择了 bean,所以@Qualifier 不能在这里应用。

      为了解决这个问题,Spring 提供了@Primary 注释以及@Bean 注释。

      Source

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-02
        • 2015-07-07
        • 2018-11-04
        • 2018-02-05
        • 2015-09-26
        • 1970-01-01
        • 2012-07-29
        • 2022-12-11
        相关资源
        最近更新 更多