1. autowire-candidate做什么事情?
上一篇文章primary能解决什么问题中遇到的问题,我们再来回顾一下,当容器中某种类型的bean存在多个实例的时候,此时我们如果从容器中查找这种类型的bean对象,会报下面这个异常:
org.springframework.beans.factory.NoUniqueBeanDefinitionException
原因:当从容器中按照类型查找一个bean对象的时候,容器中却找到了多个匹配到的bean实例,此时spring也蒙圈了不知道该如何选择了,就会报这个异常。 这种异常主要出现在两种场景中:
1.1 场景1
从容器中查找符合指定类型的bean实例,对应BeanFactory下面的方法:
<T> T getBean(Class<T> requiredType) throws BeansException;
1.2 场景2
自动注入方式设置为byType的时候,如下:
package test;
public class NormalBean {
public interface IService{}
public static class ServiceA implements IService{}
public static class ServiceB implements IService{}
private IService service;
public void setService(IService service){
this.service = service;
}
}
xml如下:
<bean id="serviceA" class="test.NormalBean.ServiceA"/>
<bean id="serviceB" class="test.NormalBean.ServiceB"/>
<bean id="setBean" class="test.NormalBean" autowire="byType"/>
setBean的autowire设置为byType,即按照setter方法的参数类型自动注入,setBean的setService的参数类型是IService,而IService类有两个实现类:ServiceA和ServiceB。
而容器中刚好管理了这两个实现类的bean:serviceA和serviceB实例。
所以上面代码会报错,不知道该选择哪个实例对象进行注入。
1.3 autowire-candidate
正如上面存在的问题,spring除了使用primary属性来解决,还有一种方法也可以解决这种问题。
可以设置某个bean是否在自动注入的时候作为候选者bean,通过bean标签的autowire-candidate属性来配置,如下:
<bean id="serviceA" class="test.NormalBean.ServiceA" autowire-candidate="false"/>
autowire-candidate:设置当前bean在被其他对象作为自动注入对象的是偶,是否作为候选者bean,其默认值是true。
来举例说明一下,以上面的setBean注入的案例说明一下注入的过程:
从上面过程中可以看出将某个bean的primary属性设置为true就可以解决问题了。
或者只保留一个bean的auto-candidate属性为true,将其余满足条件的bean的autowire-candidate设置为false,此时也可以解决多个bean实例的问题。
文档信息
- 本文作者:Marshall