为什么`autowire = byType`也会按名称注入bean?

时间:2015-01-14 06:50:32

标签: spring inversion-of-control autowired

我发现autowire=byType行为不明确。

my下的Java代码:

public class User {
    private String name;
    public User(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserService {

    @Autowired
    private User user1;
    @Autowired
    private User user2;

    public String getNames() {
        return user1.getName() + " & " + user2.getName();
    }

}

Spring config:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">

    <context:component-scan base-package="my"/>

    <context:annotation-config/>

    <bean id="user1" class="my.User" autowire="byType">
        <constructor-arg value="Freewind"/>
    </bean>

    <bean id="user2" class="my.User" autowire="byType">
        <constructor-arg value="Lily"/>
    </bean>

</beans>

运行代码:

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService service = context.getBean(UserService.class);
        System.out.println(service.getNames());
    }
}

它运作良好并打印:

Freewind & Lily

但我期待它不起作用,因为我在定义bean时使用了autowire="byType",并且在User中有两个bean具有相同类型UserService

而且,如果我更改了bean的名称,比如user1 - &gt; user999,它会报告一些错误,例如No qualifying bean of type [my.User] is defined错误。

即使我指定了byType,春天也会自动检查名称,这很奇怪。

PS:我已经使用spring 4.1.3.RELEASE3.2.2.RELEASE进行了测试,行为相同。

1 个答案:

答案 0 :(得分:1)

<bean id="user2" class="my.User" autowire="byType">
    <constructor-arg value="Lily"/>
</bean>

此处的autowire="byType"表示您希望将(缺少的)依赖项注入此bean byType。它仅适用于放置属性的bean。在xml命名空间中,可以设置所有bean的默认值。

但是在您的情况下,您实际上正在使用注释(<context:annotation-config />的使用已经暗示了注释</context:component-scan />)。注释驱动注入(@Autowired@Inject始终按类型,@Resource使用名称或jndi查找以及按名称回退。

启动应用程序并扫描每个所需依赖项的组件时,会创建DependencyDescriptor。此类包含用于自动装配的详细信息,其中包含类型和名称。在Field的情况下,名称是从实际名称派生的。