[英]Some doubts about how exactly work the XML constructor injection Spring configuration?
I am studying Sping XML configuration and I have the following doubt related to the constructor injection configuration . 我正在研究Sping XML配置,并且对构造函数注入配置有以下疑问。
So I have the following example: 因此,我有以下示例:
<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”/>
Ok. 好。 It is pretty clear for me what happens: first the accountRepository bean is created as an com.acme.AccountRepositoryImpl instance and the customerRepository bean is created as an com.acme.CustomerRepositoryImpl instance
对我来说很清楚发生了什么:首先将accountRepository bean创建为com.acme.AccountRepositoryImpl实例,并将customerRepository bean创建为com.acme.CustomerRepositoryImpl实例。
Then is created the transferService bean as an istance of the com.acme.TransferServiceImpl class and the previous 2 bean are injected as input paramether of the constructor during the bean construction. 然后创建transferService bean作为com.acme.TransferServiceImpl类的一个实例,并且在bean构造期间将前面的2个bean作为构造函数的输入参数注入。
This is clear. 这很清楚。 My doubt is related to the fact that on the documentation I read that:
我的怀疑与以下事实有关:我在文档中读到:
Parameters injected according to their type
根据类型注入参数
What it exactly means? 到底是什么意思? It seems to me that in the previous configuration the beans are injected according to their id.
在我看来,在先前的配置中,bean是根据其id注入的。
The previous statement means that Spring check the type and for example if the constructor of the TransferServiceImpl class take 2 paramethers having type AccountRepositoryImpl and CustomerRepositoryImpl it perform the matching? 前面的语句意味着Spring检查类型,例如,是否TransferServiceImpl类的构造函数采用2个参数类型为AccountRepositoryImpl和CustomerRepositoryImpl的参数,它执行匹配?
So it means that: 因此,这意味着:
<bean id=“transferService” class=“com.acme.TransferServiceImpl”>
<constructor-arg ref=“accountRepository”/>
<constructor-arg ref=“customerRepository”/>
</bean>
is the same thing of: 是同一件事:
<bean id=“transferService” class=“com.acme.TransferServiceImpl”>
<constructor-arg ref=“customerRepository”/>
<constructor-arg ref=“accountRepository”/>
</bean>
? ?
Changing the order of the paramethers the result don't change because Spring perform the matching for me? 更改参数的顺序不会改变,因为Spring为我执行了匹配? If yes what happens if in the constructor I have more paramether that have the same type?
如果是,如果在构造函数中我有更多具有相同类型的参数,会发生什么?
Tnx 特纳克斯
If every constructor parameter has different type - Spring handles it automatically - you can mix order in XML code. 如果每个构造函数参数都有不同的类型-Spring会自动处理它-您可以在XML代码中混合使用顺序。 If there is more than one with the same type then Spring just puts them in the same order as they appear in the constructor definition.
如果有多个相同类型的数据,那么Spring只会按照它们在构造函数定义中出现的顺序排列。 Let's take following example:
让我们来看下面的例子:
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 definition like: 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>
Will be handled by Spring without throwing exceptions and it will result with the object of class Project with property: 将由Spring处理而不会引发异常,并且将导致带有属性的Project类的对象:
If you want to make things right, always set index for constructor-arg: 如果您想做对的事情,请始终为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>
or for even better readability - set name property: 或为了更好的可读性-设置名称属性:
<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>
Just keep in mind that: 请记住:
(...) to make this work out of the box your code must be compiled with the debug flag enabled so that Spring can look up the parameter name from the constructor.
(...)要使此工作开箱即用,必须在启用调试标志的情况下编译代码,以便Spring可以从构造函数中查找参数名称。 If you can't compile your code with debug flag (or don't want to) you can use @ConstructorProperties JDK annotation to explicitly name your constructor arguments.
如果您无法使用调试标志(或不想这样做)来编译代码,则可以使用@ConstructorProperties JDK注释显式命名构造函数参数。
Read more in Spring reference 在Spring参考中阅读更多内容
Following is the way to handle ambiguity in constructor based injection: 以下是在基于构造函数的注入中处理歧义的方法:
Scenario 1: If you have multiple parameters, you need to use the type
attribute. 方案1:如果有多个参数,则需要使用
type
属性。 eg 例如
<constructor-arg ref=“accountRepository” type="com.acme.AccountRepositoryImpl" />
<constructor-arg ref=“customerRepository” type="com.acme.CustomerRepositoryImpl" />
Scenario 2: If you have multiple parameters of same type, you need to use the index
attribute eg 方案2:如果您有多个相同类型的参数,则需要使用
index
属性,例如
<constructor-arg index="0" value="7500000"/>
<constructor-arg index="1" value="42"/>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.