何时在 Spring 中使用 Qualifier 和 Primary

Jus*_*per 8 spring annotations

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

我也有以下疑问

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

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

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

wea*_*ver 13

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

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

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

public interface BeanInterface {

    String getName();
}

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

@Component
public class Bean2 implements BeanInterface {
    @Override
    public String getName() {
        return "bean2";
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我们的服务。

@Service
public class BeanService {

    @Autowired
    private BeanInterface bean;
}
Run Code Online (Sandbox Code Playgroud)

还有我们的配置。

@Configuration
public class Config {

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

    @Bean("bean2")
    public BeanInterface bean2() {
        return new Bean2();
    }
}
Run Code Online (Sandbox Code Playgroud)

当 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) 
Run Code Online (Sandbox Code Playgroud)

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

所以在我们的例子中,当我们添加@PrimaryConfig.bean1().

@Bean("bean1")
@Primary
public BeanInterface bean1() {
    return new Bean1();
}
Run Code Online (Sandbox Code Playgroud)

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

这里是另一种方式来自动装配bean1,以BeanService利用@QualifierBeanService.class

@Service
public class BeanService {

    @Autowired
    @Qualifier("bean1")
    private BeanInterface bean;
}
Run Code Online (Sandbox Code Playgroud)

@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);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是“bean2”。


Sha*_*ski 5

另外,需要记住,@Qualifier作为更大的优先级@Primary,这意味着定义这两个注释是浪费。

@Primary表示默认实现,表示@Qualifier具体实现。

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