java 为什么在尝试使用构造函数参数初始化 bean 时会收到 BeanCreationException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6278358/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why am I getting a BeanCreationException when trying to initialise a bean using the constructor-arg element
提问by Dunes
I'm trying create an immutable object and initialise it from xml config file in spring. But I'm getting a BeanCreationException and I haven't been able to figure out why. The exception states that it can't find an appropriate constructor with the following message:
我正在尝试创建一个不可变对象并在 spring 中从 xml 配置文件初始化它。但是我收到了 BeanCreationException 并且我无法弄清楚原因。异常指出它找不到合适的构造函数,并显示以下消息:
"Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)"
“无法解析匹配的构造函数(提示:为简单参数指定索引/类型/名称参数以避免类型歧义)”
However, if I change the constructor-arg elements to use index based argument resolution it works fine, but that won't make for nice readable config file. That is, I want name based argument resolution so it can easily be seen what the argument corresponds to.
但是,如果我将构造函数参数更改为使用基于索引的参数解析,它可以正常工作,但这不会使配置文件具有良好的可读性。也就是说,我想要基于名称的参数解析,以便可以很容易地看到参数对应的内容。
As far as I can see there is no ambiguity at all. That is, there is only one two args constructor. It takes two ints, once called 'a' and one called 'b', which is exactly what the bean element specifies
据我所知,完全没有歧义。也就是说,只有一个两个 args 构造函数。它需要两个整数,一次称为“a”,一个称为“b”,这正是 bean 元素指定的
All files are UTF-8 encoded so it can't be an encoding problem.
所有文件都是 UTF-8 编码的,所以它不可能是编码问题。
exception:
例外:
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'constructorTest' defined in class path resource [ApplicationContext.xml]: Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)
at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:250)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1003)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:907)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:291)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:288)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:190)
at com.alertme.energysmart.service.TestClass.main(TestClass.java:50)
conifg extract:
配置提取:
<bean id="constructorTest" class="testpackage.TestClass">
<constructor-arg name="a" value="0" type="int" />
<constructor-arg name="b" value="1" type="int" />
</bean>
<bean id="propertyTest" class="testpackage.TestClass">
<property name="a" value="0" />
<property name="b" value="1" />
</bean>
class:
班级:
package testpackage;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import com.alertme.lang.IgnoreNullsShortPrefixStyle;
public class TestClass {
private int a;
private int b;
public TestClass() {
// java bean
}
/**
* This is the targeted constructor
*/
public TestClass(int a, int b) {
this.a = a;
this.b = b;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public void setB(int b) {
this.b = b;
}
public int getB() {
return b;
}
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, IgnoreNullsShortPrefixStyle.get());
}
public static void main(String[] args) {
final BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("ApplicationContext.xml"));
final TestClass bean = (TestClass) beanFactory.getBean("constructorTest");
System.out.println(bean);
}
}
回答by dunni
The docs for the attribute "name" says:
属性“名称”的文档说:
Note: This requires debug symbols to be stored in the class file in order to introspect argument names!
注意:这需要将调试符号存储在类文件中以检查参数名称!
So maybe you don't have the debug symbols enabled?
所以也许你没有启用调试符号?
回答by nikhilgupta86
According to the spring docs : As of Spring 3.0 you can also use the constructor parameter name for value disambiguation: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. 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.
根据 spring 文档:从 Spring 3.0 开始,您还可以使用构造函数参数名称来消除歧义:请记住,要使此工作开箱即用,您的代码必须在启用调试标志的情况下进行编译,以便 Spring 可以查找构造函数中的参数名称。如果您无法使用调试标志(或不想)编译代码,则可以使用 @ConstructorProperties JDK 注释显式命名构造函数参数。