当找到多个匹配的 bean 时,Spring 如何按名称自动装配?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4447877/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does Spring autowire by name when more than one matching bean is found?
提问by Maniganda Prakash
Suppose I have interfaces such as these:
假设我有这样的接口:
interface Country {}
class USA implements Country {}
class UK implements Country ()
And this snippet of configuration xml:
这个配置xml片段:
<bean class="USA"/>
<bean id="country" class="UK"/>
<bean id="main" class="Main"/>
How can I control which dependency is autowired below? I'd like the UK one.
如何控制下面自动装配的依赖项?我想要英国的。
class Main {
private Country country;
@Autowired
public void setCountry(Country country) {
this.country = country;
}
}
I am using Spring 3.0.3.RELEASE.
我正在使用 Spring 3.0.3.RELEASE。
回答by skaffman
This is documented in section 3.9.3of the Spring 3.0 manual:
这记录在Spring 3.0 手册的第 3.9.3 节中:
For a fallback match, the bean name is considered a default qualifier value.
对于回退匹配,bean 名称被视为默认限定符值。
In other words, the default behaviour is as though you'd added @Qualifier("country")to the setter method.
换句话说,默认行为就像您已添加@Qualifier("country")到 setter 方法一样。
回答by Paul Whelan
You can use the @Qualifier annotation
您可以使用@Qualifier 批注
From here
从这里
Fine-tuning annotation-based autowiring with qualifiers
使用限定符微调基于注释的自动装配
Since autowiring by type may lead to multiple candidates, it is often necessary to have more control over the selection process. One way to accomplish this is with Spring's @Qualifier annotation. This allows for associating qualifier values with specific arguments, narrowing the set of type matches so that a specific bean is chosen for each argument. In the simplest case, this can be a plain descriptive value:
由于按类型自动装配可能会导致多个候选,因此通常需要对选择过程进行更多控制。实现此目的的一种方法是使用 Spring 的 @Qualifier 注释。这允许将限定符值与特定参数相关联,缩小类型匹配集,以便为每个参数选择一个特定的 bean。在最简单的情况下,这可以是一个简单的描述性值:
class Main {
private Country country;
@Autowired
@Qualifier("country")
public void setCountry(Country country) {
this.country = country;
}
}
This will use the UK add an id to USA bean and use that if you want the USA.
这将使用 UK 添加一个 id 到 USA bean,如果你想要 USA,就使用它。
回答by Ricardo Veguilla
Another way of achieving the same result is to use the @Value annotation:
实现相同结果的另一种方法是使用 @Value 注释:
public class Main {
private Country country;
@Autowired
public void setCountry(@Value("#{country}") Country country) {
this.country = country;
}
}
In this case, the "#{country}string is an Spring Expression Language (SpEL)expression which evaluates to a bean named country.
在这种情况下,该"#{country}字符串是一个Spring 表达式语言 (SpEL)表达式,其计算结果为名为country.
回答by theme
One more solution with resolving by name:
另一种按名称解析的解决方案:
@Resource(name="country")
It uses javax.annotationpackage, so it's not Spring specific, but Spring supports it.
它使用javax.annotation包,所以它不是 Spring 特定的,但 Spring 支持它。
回答by Михаил Дмитряха
in some case you can use annotation @Primary.
在某些情况下,您可以使用注释@Primary。
@Primary
class USA implements Country {}
This way it will be selected as the default autowire candididate, with no need to autowire-candidate on the other bean.
这样它将被选为默认的自动装配候选者,而无需在另一个 bean 上自动装配候选者。
for mo deatils look at Autowiring two beans implementing same interface - how to set default bean to autowire?
有关详细信息,请查看自动装配两个实现相同接口的 bean - 如何将默认 bean 设置为自动装配?

