Требуется ли 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
Это действительно необходимо?
Ответы
Ответ 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.