当发现多个匹配的 bean 时,Spring 如何通过名称自动连接?

假设我有这样的接口:

interface Country {}
class USA implements Country {}
class UK implements Country ()

还有 xml 的这个配置片段:

<bean class="USA"/>
<bean id="country" class="UK"/>
<bean id="main" class="Main"/>

我怎样才能控制哪个依赖是下面自动连接的? 我想英国的一个。

class Main {
private Country country;
@Autowired
public void setCountry(Country country) {
this.country = country;
}
}

我正在使用 Spring3.0.3。

179447 次浏览

您可以使用@Qualifier 注释

From here

使用限定符微调基于注释的自动装配

由于按类型自动装配可能导致多个候选人,通常有必要对选择过程有更多的控制。实现这一点的一种方法是使用 Spring 的@Qualifier 注释。这允许将限定符值与特定的参数相关联,从而缩小类型匹配集,以便为每个参数选择特定的 bean。在最简单的情况下,这可以是一个简单的描述性值:

class Main {
private Country country;
@Autowired
@Qualifier("country")
public void setCountry(Country country) {
this.country = country;
}
}

这将使用 UK 向 USA bean 添加一个 id,如果您希望使用 USA,则使用它。

这在 Spring 3.0手册的 第3.9.3节中有记录:

对于回退匹配,bean 名称被认为是默认的限定符值。

换句话说,默认行为就好像您已经将 @Qualifier("country")添加到 setter 方法中一样。

实现相同结果的另一种方法是使用@Value 注释:

public class Main {
private Country country;


@Autowired
public void setCountry(@Value("#{country}") Country country) {
this.country = country;
}
}

在本例中,"#{country}字符串是一个 Spring Expression Language (SpEL)表达式,其计算结果为一个名为 country的 bean。

在某些情况下,你可以使用注释@质点。

@Primary
class USA implements Country {}

这样,它将被选择为默认的自动连接候选项,而不需要在另一个 bean 上进行自动连接候选项。

更多细节请看 自动连接实现相同接口的两个 bean ——如何将默认 bean 设置为自动连接?

还有一个通过名称解决的解决方案:

@Resource(name="country")

它使用 注释包,所以它不是 Spring 特有的,但 Spring 支持它。