26

我不想为我的auditRecord类创建默认构造函数。

但Spring似乎坚持它:

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'auditRecord' defined in ServletContext resource
[/WEB-INF/applicationContext.xml]: 
Instantiation of bean failed; 
nested exception is org.springframework.beans.BeanInstantiationException: 
Could not instantiate bean class [com.bartholem.AuditRecord]: 
No default constructor found; 
nested exception is 
java.security.PrivilegedActionException:
java.lang.NoSuchMethodException: 
com.bartholem.AuditRecord

这真的有必要吗?

4

4 回答 4

32

不,您不需要使用默认(无 arg)构造函数。

你是如何定义你的bean的?听起来您可能已经告诉 Spring 实例化您的 bean,如下所示:

<bean id="AuditRecord" class="com.bartholem.AuditRecord"/>

<bean id="AnotherAuditRecord" class="com.bartholem.AuditRecord">
  <property name="someProperty" val="someVal"/>
</bean>

您没有提供构造函数参数的地方。前一个将使用默认(或无 arg)构造函数。如果要使用接受参数的构造函数,则需要使用constructor-arg元素指定它们,如下所示:

<bean id="AnotherAuditRecord" class="com.bartholem.AuditRecord">
  <constructor-arg val="someVal"/>
</bean>

如果您想在应用程序上下文中引用另一个 bean,您可以使用元素的ref属性constructor-arg而不是val属性来完成。

<bean id="AnotherAuditRecord" class="com.bartholem.AuditRecord">
  <constructor-arg ref="AnotherBean"/>
</bean>

<bean id="AnotherBean" class="some.other.Class" />
于 2011-09-20T22:47:21.290 回答
19

nicholas' answer is right on the money for XML configuration. I'd just like to point out that when using annotations to configure your beans, it's not only simpler to do constructor injection, it's a much more natural way to do it:

class Foo {
    private SomeDependency someDependency;
    private OtherDependency otherDependency;

    @Autowired
    public Foo(SomeDependency someDependency, OtherDependency otherDependency) {
        this.someDependency = someDependency;
        this.otherDependency = otherDependency;
    }
}
于 2011-09-21T02:05:10.867 回答
1

您可能能够进行基于构造函数的注入,即类似这样的事情(取自此处找到的文档)

<bean id="foo" class="x.y.Foo">
    <constructor-arg ref="bar"/>
    <constructor-arg ref="baz"/>
</bean>

但我不确定它会起作用。

如果要定义 JavaBean,则需要遵循约定并在其上放置一个公共的无参数构造函数。

于 2011-09-20T22:45:09.260 回答
0

几乎所有 Java 开发人员都知道编译器会在每个 Java 类中添加一个默认构造函数,或者更好地称为无参数构造函数,但他们中的许多人忘记了它只有在您不提供任何其他构造函数时才会这样做。这意味着如果要添加显式构造函数,则添加无参数构造函数成为开发人员的责任。现在,为什么在 Java 中提供默认构造函数很重要,如果你的类没有无参数构造函数会发生什么?嗯,这就是在许多 Java 面试中被问到的方式,最常见的是作为 Spring 和 Hibernate 面试的一部分。

您应该始终在您的 Java 类中定义一个无参数构造函数,即使您正在编写一个显式构造函数,直到您完全确定它不会使用反射来实例化并且在没有参数构造函数的情况下实例化它是一个错误,就像在您的 Spring Bean 示例。

于 2021-03-25T06:53:49.170 回答