开发者

Why am I getting a BeanCreationException when trying to initialise a bean using the constructor-arg element

开发者 https://www.devze.com 2023-03-11 16:39 出处:网络
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

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:

"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

All files are UTF-8 encoded so it can't be an encoding problem.

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$1.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);       
    }

}


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?


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消