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


106

假设我有这样的接口:

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。


我想我会补充一点,我在一个(测试)环境中得到“没有类型的独特bean ...”,并且在我的开发环境中运行良好。我确信这是某种类路径,但是事实证明,如果添加@Qualifier,它就可以正常工作。
markthegrea 2012年

Answers:


113

在Spring 3.0手册的3.9.3节中对此进行了说明:

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

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


当您说“ bean name”时,您的意思是将包含bean的字段的名称吗?(即本例country
基金莫妮卡的诉讼

67

您可以使用@Qualifier批注

这里

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

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

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

这将使用UK向USA bean添加一个ID,如果需要USA,则使用该ID。


12

获得相同结果的另一种方法是使用@Value批注:

public class Main {
     private Country country;

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

在这种情况下,"#{country}字符串是Spring表达式语言(SpEL)表达式,其计算结果为名为的bean country


可以根据财产注入吗?如果USA或UK是来自URL的某种参数,而我想基于参数是2种不同的东西怎么办?
Kalpesh Soni 2015年

6

通过名称解析的另一种解决方案:

@Resource(name="country")

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


1
@Resource不会在那里出的现成的Java 11由于拼图模块
德克·霍夫曼

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.