有些人怀疑XML构造函数如何正确地注入Spring配置?

时间:2014-11-17 17:11:18

标签: java spring spring-mvc dependency-injection frameworks

我正在研究Sping XML配置,我对构造函数注入配置有疑问。

所以我有以下例子:

<bean id=“transferService” class=“com.acme.TransferServiceImpl”>
    <constructor-arg ref=“accountRepository”/>
    <constructor-arg ref=“customerRepository”/>
</bean>

<bean id=“accountRepository” class=“com.acme.AccountRepositoryImpl”/>
<bean id=“customerRepository” class=“com.acme.CustomerRepositoryImpl”/>

确定。我很清楚会发生什么:首先将 accountRepository bean创建为 com.acme.AccountRepositoryImpl 实例,并创建 customerRepository bean作为 com.acme.CustomerRepositoryImpl 实例

然后创建 transferService bean作为 com.acme.TransferServiceImpl 类的istance,并且在bean期间将前两个bean作为构造函数的输入参数注入构造

这很清楚。我怀疑是这样的事实,在我阅读的文件中:

  

根据类型注入的参数

它究竟意味着什么?在我看来,在之前的配置中,bean是根据他们的id注入的。

前面的语句意味着Spring检查类型,例如 TransferServiceImpl 类的构造函数是否有2个参数类型 AccountRepositoryImpl CustomerRepositoryImpl 它执行匹配?

所以这意味着:

<bean id=“transferService” class=“com.acme.TransferServiceImpl”>
    <constructor-arg ref=“accountRepository”/>
    <constructor-arg ref=“customerRepository”/>
</bean>

是同样的事情:

<bean id=“transferService” class=“com.acme.TransferServiceImpl”>
    <constructor-arg ref=“customerRepository”/>
    <constructor-arg ref=“accountRepository”/>
</bean>

更改参数的顺序,结果不会改变,因为Spring为我执行匹配?如果是,如果在构造函数中我有更多具有相同类型的参数,会发生什么?

TNX

2 个答案:

答案 0 :(得分:3)

如果每个构造函数参数都有不同的类型--Spring会自动处理它 - 您可以在XML代码中混合顺序。如果有多个具有相同类型的Spring,那么Spring只是按照它们在构造函数定义中出现的顺序放置它们。我们来看下面的例子:

public class User {
    private String name;

    public User(String name) {
        this.name = name;
    }
}

public class Project {
    private User user1;
    private User user2;
    private int cost;

    public Project(User user1, User user2, int cost) {
        this.user1 = user1;
        this.user2 = user2;
        this.cost = cost;
    }
}

Bean定义如:

<bean id="user1" class="demo.User">
    <constructor-arg value="User1" />
</bean>

<bean id="user2" class="demo.User">
    <constructor-arg value="User2" />
</bean>

<bean id="proj" class="demo.Project">
    <constructor-arg value="100" />
    <constructor-arg ref="user2" />
    <constructor-arg ref="user1" />
</bean>

将由Spring处理而不抛出异常,它将导致类Project的对象具有属性:

  • user1 = bean(user2)
  • user2 = bean(user1)
  • 费用= 100

如果你想把事情做好,总是为constructor-arg设置 index

<bean id="proj" class="demo.Project">
    <constructor-arg index="0" ref="user1" />
    <constructor-arg index="1" ref="user2" />
    <constructor-arg index="2" value="100" />
</bean>

或为了更好的可读性 - 设置名称属性:

<bean id="proj" class="demo.Project">
    <constructor-arg name="cost" value="100" />
    <constructor-arg name="user2" ref="user2" />
    <constructor-arg name="user1" ref="user1" />
</bean>

请记住:

  

(...)为了使这项工作开箱即用,您的代码必须在启用调试标志的情况下编译,以便Spring可以从构造函数中查找参数名称。如果无法使用debug标志编译代码(或者不想),可以使用@ConstructorProperties JDK批注来明确命名构造函数参数。

Spring reference

中了解详情

答案 1 :(得分:2)

以下是处理基于构造函数的注入中的歧义的方法:

场景1: 如果您有多个参数,则需要使用type属性。 e.g。

<constructor-arg ref=“accountRepository” type="com.acme.AccountRepositoryImpl" />
<constructor-arg ref=“customerRepository” type="com.acme.CustomerRepositoryImpl" />

场景2: 如果您有多个相同类型的参数,则需要使用index属性,例如

<constructor-arg index="0" value="7500000"/>
<constructor-arg index="1" value="42"/>
相关问题