web-dev-qa-db-fra.com

Spring nécessite-t-il que tous les beans aient un constructeur par défaut?

Je ne veux pas créer un constructeur par défaut pour ma classe auditRecord.

Mais le printemps semble y insister:

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

Est-ce vraiment nécessaire?

25
Koo Park

Non, vous n'êtes pas obligé d'utiliser des constructeurs par défaut (pas d'argument).

Comment avez-vous défini votre bean? On dirait que vous avez peut-être dit à Spring d'instancier votre bean quelque chose comme l'un d'eux:

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

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

Où vous n'avez pas fourni d'argument constructeur. Le précédent utilisera des constructeurs par défaut (ou sans arg). Si vous souhaitez utiliser un constructeur qui accepte des arguments, vous devez les spécifier avec le constructor-arg élément comme ceci:

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

Si vous souhaitez référencer un autre bean dans votre contexte d'application, vous pouvez le faire en utilisant l'attribut ref de constructor-arg élément plutôt que l'attribut val.

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

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

la réponse de nicholas est juste sur l'argent pour la configuration XML. Je voudrais juste souligner que lorsque vous utilisez des annotations pour configurer vos beans, ce n'est pas seulement plus simple de faire l'injection de constructeur, c'est une manière beaucoup plus naturelle de le faire:

class Foo {
    private SomeDependency someDependency;
    private OtherDependency otherDependency;

    @Autowired
    public Foo(SomeDependency someDependency, OtherDependency otherDependency) {
        this.someDependency = someDependency;
        this.otherDependency = otherDependency;
    }
}
19
Ryan Stewart

Vous pourriez être en mesure de faire une injection basée sur un constructeur, c'est-à-dire quelque chose comme ça (tiré de la documentation trouvée ici )

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

mais je ne suis pas sûr que cela fonctionnera.

Si vous définissez un JavaBean, vous devez suivre la convention et y mettre un constructeur public sans argument.

1
hvgotcodes