Требует ли Spring, чтобы все bean-компоненты имели конструктор по умолчанию?

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

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


person Koo Park    schedule 20.09.2011    source источник
comment
Пожалуйста, покажите вашу конфигурацию, которая загружает bean-компонент - XML ​​или аннотации   -  person atrain    schedule 21.09.2011
comment
stackoverflow.com/questions/25272543/   -  person newday    schedule 20.06.2017


Ответы (4)


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

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

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

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

Если вы не предоставили аргумент конструктора. Предыдущий будет использовать конструкторы по умолчанию (или без аргументов). Если вы хотите использовать конструктор, который принимает аргументы, вам нужно указать их с помощью элемента constructor-arg следующим образом:

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

Если вы хотите сослаться на другой компонент в контексте вашего приложения, вы можете сделать это, используя атрибут ref элемента constructor-arg, а не атрибут val.

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

<bean id="AnotherBean" class="some.other.Class" />
person nicholas.hauschild    schedule 20.09.2011

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

class Foo {
    private SomeDependency someDependency;
    private OtherDependency otherDependency;

    @Autowired
    public Foo(SomeDependency someDependency, OtherDependency otherDependency) {
        this.someDependency = someDependency;
        this.otherDependency = otherDependency;
    }
}
person Ryan Stewart    schedule 21.09.2011
comment
У меня есть небольшая проблема с этим. Эта аннотация работает в одной части приложения, но в тесте я получаю ошибку «без конструктора без аргументов». Не могли бы вы сказать, есть ли способ решить эту проблему без ввода аргументов или добавления конструктора по умолчанию? - person John Doe; 12.06.2012
comment
@JohnDoe: вам нужно задать новый вопрос, а не публиковать комментарий к действительно старому ответу. Кроме того, если это все, что касается вашего вопроса, вы не получите хорошего ответа. Включите трассировку стека и пример кода, чтобы продемонстрировать свою проблему. См. SSCCE. См. также Как спросить. - person Ryan Stewart; 13.06.2012

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

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

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

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

person hvgotcodes    schedule 20.09.2011

Почти все Java-разработчики знают, что компилятор добавляет конструктор по умолчанию или, более известный как конструктор без аргументов, в каждый класс Java, но многие из них забывают, что это происходит только тогда, когда вы не предоставляете никакого другого конструктора. Это означает, что разработчики несут ответственность за добавление конструктора без аргументов, если он добавляет явный конструктор. Теперь, почему важно предоставить конструктор по умолчанию в Java. Что произойдет, если в вашем классе нет конструктора без аргументов? Вот как об этом спрашивают во многих интервью по Java, чаще всего в рамках интервью по Spring и Hibernate.

Вы всегда должны определять конструктор без аргументов в своем классе Java, даже если вы пишете явный конструктор, пока вы не будете абсолютно уверены, что он не будет создан с использованием отражения, а его создание без конструктора аргументов является ошибкой, как в ваш пример Spring Bean.

person Meghraj Sharma    schedule 25.03.2021