【发布时间】:2019-06-18 05:38:13
【问题描述】:
我读过@Qualifier 可以用于注入阶段,而@Primary 用于配置阶段。我还不清楚什么时候用哪个。
我也有以下疑问
@Primary 和@Qualifier 可以一起使用吗?如果是,@Qualifier 是否优先?
@Primary 可以与@Autowired 一起使用吗?
注入阶段与配置阶段有何不同,这与 Spring bean 相关
【问题讨论】:
标签: spring annotations
我读过@Qualifier 可以用于注入阶段,而@Primary 用于配置阶段。我还不清楚什么时候用哪个。
我也有以下疑问
@Primary 和@Qualifier 可以一起使用吗?如果是,@Qualifier 是否优先?
@Primary 可以与@Autowired 一起使用吗?
注入阶段与配置阶段有何不同,这与 Spring bean 相关
【问题讨论】:
标签: spring annotations
@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 中使用@Qualifier 将bean1 自动连接到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”。
【讨论】:
@Component 标记类定义,因为您已经用@Bean 注释了配置类中的方法名称,在这种情况下就足够了。不过答案很好!
另外,需要记住@Qualifier 的优先级高于@Primary,这意味着定义两个注解是浪费的。
@Primary是默认实现,@Qualifier是具体实现。
您可以查看我写的关于此注释的博客 - http://shaikezam.com/spring_qualifier
【讨论】:
是的,@Qualifier 优先。 是的,我们可以同时使用@Primary 和@Autowired。
@Configuration 与应用程序上下文相关的类,可用于配置应用程序级别的配置。
【讨论】:
要访问具有相同类型的bean,我们通常使用@Qualifier(“beanName”) 注解。我们将它与@Autowired 一起应用在注入点。在我们的例子中,我们在配置阶段选择了 bean,所以@Qualifier 不能在这里应用。
为了解决这个问题,Spring 提供了@Primary 注释以及@Bean 注释。
【讨论】: