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

nov*_*ice 102 spring

假设我有这样的接口:

interface Country {}
class USA implements Country {}
class UK implements Country ()
Run Code Online (Sandbox Code Playgroud)

这个配置xml片段:

<bean class="USA"/>
<bean id="country" class="UK"/>
<bean id="main" class="Main"/>
Run Code Online (Sandbox Code Playgroud)

如何控制下面自动连接的依赖项?我想要英国人.

class Main {
    private Country country;
    @Autowired
    public void setCountry(Country country) {
        this.country = country;
    }
}
Run Code Online (Sandbox Code Playgroud)

我使用的是Spring 3.0.3.RELEASE.

ska*_*man 108

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

对于回退匹配,bean名称被视为默认限定符值.

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


Pau*_*lan 64

您可以使用@Qualifier注释

这里开始

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

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

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

这将使用UK为USA bean添加id,如果你想要美国,可以使用它.


Ric*_*lla 12

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

public class Main {
     private Country country;

     @Autowired
     public void setCountry(@Value("#{country}") Country country) {
          this.country = country;
     }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,"#{country}字符串是一个Spring表达式语言(SpEL)表达式,它表示一个名为的bean country.


Мих*_*яха 5

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

@Primary
class USA implements Country {}
Run Code Online (Sandbox Code Playgroud)

这样,它将被选择为默认的自动装配候选,而无需在另一个bean上自动装配候选。

欲了解更多信息,请参见自动装配实现相同接口的两个 bean- 如何将默认bean设置为自动装配?


the*_*eme 5

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

@Resource(name="country")
Run Code Online (Sandbox Code Playgroud)

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

  • 但由于 jigsaw 模块,`@Resource` 不会在 java 11 中开箱即用 (2认同)