在运行时,除非在启用了调试选项的情况下编译类,否则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{@Beanpublic Address address1(){return new Address();}@Beanpublic Person person1(){return new Person('First1', 'Last1', address1());}@Beanpublic 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