繁体   English   中英

关于XML构造函数注入Spring配置如何工作的一些疑问?

[英]Some doubts about how exactly work the XML constructor injection Spring configuration?

我正在研究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类的一个实例,并且在bean构造期间将前面的2个bean作为构造函数的输入参数注入。

这很清楚。 我的怀疑与以下事实有关:我在文档中读到:

根据类型注入参数

到底是什么意思? 在我看来,在先前的配置中,bean是根据其id注入的。

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

因此,这意味着:

<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为我执行了匹配? 如果是,如果在构造函数中我有更多具有相同类型的参数,会发生什么?

特纳克斯

如果每个构造函数参数都有不同的类型-Spring会自动处理它-您可以在XML代码中混合使用顺序。 如果有多个相同类型的数据,那么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类的对象:

  • 用户1 =豆(用户2)
  • user2 = bean(用户1)
  • 费用= 100

如果您想做对的事情,请始终为builder-arg设置索引

<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可以从构造函数中查找参数名称。 如果您无法使用调试标志(或不想这样做)来编译代码,则可以使用@ConstructorProperties JDK注释显式命名构造函数参数。

Spring参考中阅读更多内容

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

方案1:如果有多个参数,则需要使用type属性。 例如

<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"/>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM