一个简单的测试购物应用程序,我有两个类服装和优惠。 现在,在调用 formalshirt bean时,它会抛出以下异常
Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'DiwaliOffer' defined in class path resource [spring.xml]: Instantiation of bean failed;
nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [Offers]: No default constructor found;
nested exception is java.lang.NoSuchMethodException: Offers.<init>()
现在,如果我对Offers构造函数进行评论,则该应用程序将成功运行。我的查询是为什么Spring只在有另一个构造函数时才查找默认构造函数?
服装类
public class Clothing {
private int price;
private List<Offers> offer;
public void setOffer(List<Offers> offer) {
this.offer = offer;
}
public void setPrice(int price) {
this.price = price;
}
}
。
提供课程
public class Offers {
private int discount;
private String promocode;
public Offers(int val1, String val2)
{
this.discount=val1;
this.promocode=val2;
}
//public Offers(){} /*Default Constructor added due to Spring Exception as in below */
/* Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class No default constructor found */
/* Caused by: java.lang.NoSuchMethodException: com.test.Shopping.Offers.<init>() */
public void setDiscount(int discount) {
this.discount = discount;
}
public void setPromocode(String promocode) {
this.promocode = promocode;
}
}
Spring.xml
<bean id="formalshirt" class="com.test.Shopping.Clothing">
<property name="price" value="800"></property>
<property name="offer">
<list>
<ref bean="DiwaliOffer" />
</list>
</property>
</bean>
<bean id="DiwaliOffer" class="com.test.Shopping.Offers">
<property name="discount" value="10"></property>
<property name="promocode" value="diwali"></property>
</bean>
答案 0 :(得分:2)
您需要将Offers
的Spring XML配置更改为:
<bean id="DiwaliOffer" class="com.test.Shopping.Offers">
<constructor-arg value="10"></constructor-arg>
<constructor-arg value="diwali"></constructor-arg>
</bean>
你配置它的方式,Spring首先尝试调用默认构造函数,然后调用setter。但是当然没有默认的构造函数,因此Spring会报告异常。
如果使用Spring 3+,另一个选择是使用Java Config,而不是XML配置。 你只需要
@Configuration
public class AppConfig {
//add other beans
@Bean
public Offers DiwaliOffer() {
return new Offers(10, diwali);
}
}
在您的情况下,如果您没有调用构造函数,Java Config的好处是您的配置甚至无法编译,即。它会提前失败,而不是像XML配置那样迟到失败
Spring对于如何创建bean非常灵活,但你需要声明它将如何完成
答案 1 :(得分:1)
这是因为当您添加parametrize constructor
时,您需要通过提供spring
参数告诉constructor
无效......
这个概念很简单:
在默认的constriuctor情况下,您只需创建像new Test()
;
当你没有默认而不是参数化构造函数时,你必须创建像new Test1("test")
这样的对象;
Class Test{
}
Class Test1{
Test1(String a){
}
}
Spring方式将是:
<bean id="test1" class="Test1">
<constructor-arg value="Zara"/>
</bean
请查看Spring Doc了解更多详情
答案 2 :(得分:1)
您需要为您的bean属性使用constructor-args,以便它选择非默认构造函数。否则Spring首先创建对象,并且没有任何参数,它必须使用零参数构造函数,然后使用setter设置属性。
要传入构造函数args,请将属性更改为constructor-arg,如下所示:
<bean id="DiwaliOffer" class="com.test.Shopping.Offers">
<constructor-arg index="0" value="10"/>
<constructor-arg index="1" value="diwali" />
</bean>
答案 3 :(得分:0)
如果类中有任何constructor
,则java编译器不提供默认构造函数。
我们可以看到com.test.Shopping.Clothing
能够创建实例而com.test.Shopping.Offers
能够创建实例。
要创建实例,您需要传递constructor-arg
discount
和promocode
的{{1}}。
<bean id="DiwaliOffer" class="com.test.Shopping.Offers">
<constructor-arg value="10"></property>
<constructor-arg value="diwali"></property>
</bean>
答案 4 :(得分:0)
你可以这样做:
<bean id="DiwaliOffer" class="com.test.Shopping.Offers" >
<constructor-arg type="int" value="10" />
<constructor-arg type="java.lang.String" value="Diwali"/>
</bean>
bean元素中的constructor-arg元素用于通过构造函数注入设置属性值。由于User bean类中只有一个构造函数,因此该代码可以正常工作。