当找到多个匹配的bean时,Spring如何按名称自动装配?

时间:2010-12-15 08:04:32

标签: 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;
    }
}

我正在使用Spring 3.0.3.RELEASE。

5 个答案:

答案 0 :(得分:101)

这在Spring 3.0手册的section 3.9.3中有记载:

  

对于后备匹配,bean名称被视为默认限定符值。

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

答案 1 :(得分:59)

您可以使用@Qualifier注释

来自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,可以使用它。

答案 2 :(得分:12)

实现相同结果的另一种方法是使用@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。

答案 3 :(得分:5)

另一个按名称解析的解决方案:

{{1}}

它使用 javax.annotation 包,因此它不是特定于Spring的,但Spring支持它。

答案 4 :(得分:4)

在某些情况下,您可以使用注释@Primary。

@Primary
class USA implements Country {}

这样它将被选为默认的autowire候选者,不需要在另一个bean上使用autowire候选者。

for mo deatils查看Autowiring two beans implementing same interface - how to set default bean to autowire?