spring 构造函数注入
在运行时,除非在启用了调试选项的情况下编译类,否则Java类不会保留构造函数或方法参数的名称。
这对于Spring构造函数注入有一些有趣的含义。
考虑以下简单的类
package dbg;
public class Person {
private final String first;
private final String last;
private final Address address;
public Person(String first, String last, Address address){
this.first = first;
this.last = last;
this.address = address;
}
public String getFirst() {
return first;
}
public String getLast() {
return last;
}
public Address getAddress() {
return address;
}
}
和一个示例Spring bean配置xml文件:
<bean name='address1' class='dbg.Address' p:street1='street1' p:street2='street1' p:state='state1'/>
<bean name='person1' class='dbg.Person' c:address-ref='address1' c:last='Last1' c:first='First1' ></bean>
<bean name='person2' class='dbg.Person' c:first='First2' c:address-ref='address1' c:last='Last2' ></bean>
在这里,我使用c名称空间进行构造函数注入。 失败的原因是参数类型不明确-这是因为第一个参数是String,并且由于其运行时表示中不存在参数名称,因此Spring无法确定应使用名称还是姓氏代替它。 这种情况下有几个修复方法:1.要使用基于索引的构造函数注入,虽然缺点是非常冗长:
<bean name='person1' class='dbg.Person' >
<constructor-arg value='First1'></constructor-arg>
<constructor-arg value='Last1'></constructor-arg>
<constructor-arg ref='address1'></constructor-arg>
</bean>
<bean name='person2' class='dbg.Person' >
<constructor-arg value='First2'></constructor-arg>
<constructor-arg value='Last2'></constructor-arg>
<constructor-arg ref='address1'></constructor-arg>
</bean>
2.要使用调试符号进行编译,可以通过向Java编译器传递-g或-g:var标志来完成–这将确保参数名称保留在类文件中,并使用c保留原始的简洁bean配置。名称空间将起作用。 3.巧妙的解决方法是使用@ConstructorProperties注释构造函数,该结构基本上为Spring提供参数名称:
public class Person {
private final String first;
private final String last;
private final Address address;
@ConstructorProperties({'first','last','address'})
public Person(String first, String last, Address address){
this.first = first;
this.last = last;
this.address = address;
}
无论打开或不打开调试选项,此功能都可以使用。 4.可能最好的解决方法是简单地使用@Configuration定义bean:
@Configuration
public static class TestConfiguration{
@Bean
public Address address1(){
return new Address();
}
@Bean
public Person person1(){
return new Person('First1', 'Last1', address1());
}
@Bean
public Person person2(){
return new Person('First2', 'Last2', address1());
}
}
参考: all和其他博客中来自JCG合作伙伴 Biju Kunjummen的Spring构造函数注入和参数名称 。
翻译自: https://www.javacodegeeks.com/2012/10/spring-constructor-injection-and-argument-names.html
spring 构造函数注入