Подтвердить что ты не робот

Требуется ли Spring для всех beans иметь конструктор по умолчанию?

Я не хочу создавать конструктор по умолчанию для моего класса 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

Это действительно необходимо?

4b9b3361

Ответ 1

Нет, вам не обязательно использовать конструкторы default (no arg).

Как вы определили свой bean? Похоже, вы сказали Spring создать экземпляр bean что-то вроде этого:

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

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

Если вы не указали аргумент конструктора. Предыдущие будут использовать конструкторы default (или no 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" />

Ответ 2

Ответ Николаса справедлив в отношении денег для конфигурации XML. Я просто хотел бы отметить, что при использовании аннотаций для настройки beans, это не только упрощает конструкторскую инъекцию, но гораздо более естественный способ сделать это:

class Foo {
    private SomeDependency someDependency;
    private OtherDependency otherDependency;

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

Ответ 3

Возможно, вы сможете сделать инъекцию на основе конструктора, т.е. что-то вроде этого (взято из найденной документации здесь)

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

но я не уверен, что это сработает.

Если вы определяете JavaBean, вам нужно следовать соглашению и помещать на него публичный конструктор no-arg.