开发者

Does Spring require all beans to have a default constructor?

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 be开发者_StackOverflowan 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?


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" />


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


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.


Almost all Java developers know that compiler adds a default constructor or better known as a no-argument constructor in every Java class, but many of them forget that it only does when you don't provide any other constructor. This means it becomes the developers' responsibility to add a no-argument constructor if he is adding explicit constructor. Now, Why it's important to provide default constructor in Java, What happens if your class doesn't have a no-argument constructor? Well, this is how it's asked in many Java interviews, most commonly as part of Spring and Hibernate interviews.

You should always define a no argument constructor in your Java class, even if you are writing an explicitly constructor, until you are absolutely sure that, it's won't be instantiated using reflection and instantiating it with no argument constructor is a bug, like in your example of Spring Bean.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜