1.问题
使用 @Autowired 注解是 Spring 依赖注入的绝好方法。
但当容器中有多个相同类型的Bean实例时,如果没用正确使用实例名注入对象,则会抛出异常 NoUniqueBeanDefinitionException
提示有多个满足条件的Bean,无法正确判断使用哪一个,如下案例
@Component("Sun")
public class Sun implements Student {
public String printName() {
return "Sun";
}
}
@Component("Lee")
public class Lee implements Student {
public String printName() {
return "Lee";
}
}
@Component
public class LeeStudent {
@Autowired
private Student student;
}
两个Student类型的组件Sun和Lee,使用@Autowired进行依赖注入时没有使用正确的name,Spring将无法分辨出到底要使用哪一个实例。
2. 解决方案 @Qualifier
@Qualifier 就是为此存在的,使用它可以明确的告诉Spring我们要注入的对象。
避免让Spring脑裂,我们要在@Component或者@Bean注解中声明value属性的值。
@Component
public class LeeStudent {
@Autowired
@Qualifier("Lee")
private Student student;
student.printName(); //Lee
}
同样适用于XML的配置方式
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans">
<context:annotation-config/>
<!-- Definition for Student bean -->
<bean id="Student" class="com.sun.Student">
</bean>
<!-- Definition for Sun bean -->
<bean id="Sun" class="com.sun.Student">
<property name="name" value="Sun" />
</bean>
<!-- Definition for Lee bean -->
<bean id="Lee" class="com.sun.Student">
<property name="name" value="Lee" />
</bean>
</beans>
3. @Primary
@Primary 的注解,也可以用来处理Bean注入时的歧义。
当存在多个相同类型的 bean 时,此注解定义了首选项。除非另有说明,否则将使用 @Primary注解的bean 。