And*_*tin 5 java spring constructor
我试图按照Mkyong上有关Spring 的教程进行学习。我创建了两个简单的类,Customer和Person,如下所示:
客户:
public class Customer {
private Person person;
public Customer() {
}
//Getters and setters for person here
public String toString() {
return "Customer [person=" + person +"]";
}
}
Run Code Online (Sandbox Code Playgroud)
人物:
public class Person {
private String name;
private String address;
private int age;
public Person() {
}
public Person(String name, String address, int age) {
this.name = name;
this.address = address;
this.age = age;
}
//All getters and setters
public String toString() {
return "Person [address=" + address + ", age=" + age + ", name=" + name + "]";
}
}
Run Code Online (Sandbox Code Playgroud)
然后,我使用一个内部bean创建了一个Bean配置文件(这就是我上教程的原因),如下所示:
// Standard bean declarations
<bean id="CustomerBean" class="com.andrew.SpringInnerBeans.Customer">
<property name="person">
<bean class="com.andrew.SpringInnerBeans.Person">
<property name="name" value="Andrew" />
<property name="address" value="Address" />
<property name="age" value="27" />
</bean>
</property>
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
最后,我创建了一个MainApp来运行以下代码:
public static void main (String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {
"NewBean.xml"});
Customer cust = (Customer) context.getBean("CustomerBean");
System.out.println(cust);
}
Run Code Online (Sandbox Code Playgroud)
现在,据我了解,这是正在发生的事情:
将加载xml文件,并将ID为CustomerBean的bean存储在引用cust(这是一个Customer对象)中。CustomerBean带有一个参数“ person”,创建Person的三个参数的详细信息作为customerBean的内部bean提供。
在MainApp中,将调用参考客户的toString方法,并显示正确的输出。
正如我在示例中专门提供引用一样,为什么需要无参数构造函数来运行此代码?如果删除空的Customer或空的Person构造函数,则代码将失败。当我设置的bean不需要无参数构造函数时,为什么它在运行时失败?
编辑:
代码传递示例:
Customer [person=Person [address=4 Ascot House, age=27, name=Andrew]]
Run Code Online (Sandbox Code Playgroud)
代码示例失败:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CustomerBean' defined in class path resource [NewBean.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.andrew.SpringInnerBeans.Customer]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.andrew.SpringInnerBeans.Customer.<init>()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1040)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:505)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
at com.andrew.SpringInnerBeans.MainApp.main(MainApp.java:10)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.andrew.SpringInnerBeans.Customer]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.andrew.SpringInnerBeans.Customer.<init>()
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1088)
... 13 more
Caused by: java.lang.NoSuchMethodException: com.andrew.SpringInnerBeans.Customer.<init>()
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.getDeclaredConstructor(Unknown Source)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
... 14 more
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CustomerBean' defined in class path resource [NewBean.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.andrew.SpringInnerBeans.Customer]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.andrew.SpringInnerBeans.Customer.<init>()
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1095)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1040)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:505)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
at com.andrew.SpringInnerBeans.MainApp.main(MainApp.java:10)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.andrew.SpringInnerBeans.Customer]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.andrew.SpringInnerBeans.Customer.<init>()
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1088)
... 13 more
Caused by: java.lang.NoSuchMethodException: com.andrew.SpringInnerBeans.Customer.<init>()
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.getDeclaredConstructor(Unknown Source)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
... 14 more
Run Code Online (Sandbox Code Playgroud)
我们再从 Spring 容器的角度来看一下您所问的问题。
Customer,只有属性:好的,new Customer()使用无参数构造函数创建它并暂时保留它。Person找到一个只有属性的类 bean :好的,将其创建为new Person(),仍然使用无参数构造函数,给它一个任意名称并暂时保留它Person使用 setters填充bean 的属性:好的,它已经准备好了Customer使用 setter 和bean 作为参数来填充bean 的唯一属性Person:好的,它已准备就绪因此,您从应用程序上下文中获取 bean,并且在您自己的代码中没有new这些 bean,但是 Spring 已经为您构建了它们,并且确实使用了无参数构造函数。
例如,您可以改为:
public class Customer {
private Person person;
public Customer(Person person) {
this.person = person;
}
...
}
Run Code Online (Sandbox Code Playgroud)
你的 XML 必须是:
<bean id="CustomerBean" class="com.andrew.SpringInnerBeans.Customer">
<constructor-arg>
<bean class="com.andrew.SpringInnerBeans.Person">
<property name="name" value="Andrew" />
<property name="address" value="Address" />
<property name="age" value="27" />
</bean>
</constructor-arg>
</bean>
Run Code Online (Sandbox Code Playgroud)
这样,Spring 将首先像上面那样构造bean,并使用一个 arg 构造函数Person创建Customerbean 。new Customer(person)
| 归档时间: |
|
| 查看次数: |
2316 次 |
| 最近记录: |