Does Spring require all beans to have a default constructor?

社会主义新天地 提交于 2019-12-28 06:27:30

问题


I don't want to create a default constructor for my auditRecord class.

But Spring seems to insist on it:

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

Is this really necessary?


回答1:


No, you are not required to use default (no arg) constructors.

How did you define your bean? It sounds like you may have told Spring to instantiate your bean something like one of these:

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

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

Where you did not provide a constructor argument. The previous will use default (or no arg) constructors. If you want to use a constructor that takes in arguments, you need to specify them with the constructor-arg element like so:

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

If you want to reference another bean in your application context, you can do it using the ref attribute of the constructor-arg element rather than the val attribute.

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

<bean id="AnotherBean" class="some.other.Class" />



回答2:


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;
    }
}



回答3:


You might be able to do constructor based injection, i.e. something like this (taken from documentation found here)

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

but I'm not sure it will work.

If you are defining a JavaBean, you need to follow the convention and put a public no-arg constructor on it.



来源:https://stackoverflow.com/questions/7492652/does-spring-require-all-beans-to-have-a-default-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!