Spring MVC не найден конструктор по умолчанию?
У меня проблемы с моими контроллерами Spring - я не получаю никакого конструктора по умолчанию, но у них есть конструктор, который я пытаюсь создать через applicationContext.xml - это соответствующий бит:
<bean id="PcrfSimulator" class="com.rory.services.pcrf.simulator.PcrfSimulator" init-method="start">
</bean>
<bean id="CacheHandler" class="com.rory.services.pcrf.simulator.handlers.CacheHandler">
<constructor-arg index="0" type="com.rory.services.pcrf.simulator.CustomGxSessionIdCacheImpl">
<bean factory-bean="PcrfSimulator" factory-method="getGxSessionIdCache">
</bean>
</constructor-arg>
</bean>
Т.е. Сначала я создаю bean, а затем пытаюсь передать результат вызова метода из этого bean во второй конструктор bean (CacheHandler).
Вот начало CacheHandler:
@Controller
public class CacheHandler {
private final CustomGxSessionIdCacheImpl gxSessionIdCache;
public CacheHandler(CustomGxSessionIdCacheImpl gxSessionIdCache) {
this.gxSessionIdCache = gxSessionIdCache;
}
Вот ошибка, которую я получаю:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cacheHandler' defined in URL [jar:file:/users/rtorney/Documents/apache-tomcat-7.0.25/webapps/PCRFSimulator-4.0/WEB-INF/lib/PCRFSimulator-4.0.jar!/com/rory/services/pcrf/simulator/handlers/CacheHandler.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.rory.services.pcrf.simulator.handlers.CacheHandler]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.rory.services.pcrf.simulator.handlers.CacheHandler.<init>()
Любая помощь очень ценится!
Ответы
Ответ 1
Вы должны либо определить свой beans в xml, либо аннотировать их, а не оба (хотя бы для того, чтобы избежать ошибок, подобных тем, которые вы получаете).
Проблема в том, что вы не autowiring конструктор args, поэтому spring не знает, что делать с вашим контроллером. Он знает, что он должен создать аннотацию bean (@Controller
), но он не знает, как (нет конструктора по умолчанию, ни конструктора).
Вы можете попробовать сделать что-то вроде:
@Controller
public class CacheHandler {
private final CustomGxSessionIdCacheImpl gxSessionIdCache;
@Autowired
public CacheHandler(CustomGxSessionIdCacheImpl gxSessionIdCache) {
this.gxSessionIdCache = gxSessionIdCache;
}
а затем в xml:
<bean id="gxSessionIdCache"
factory-bean="PcrfSimulator"
factory-method="getGxSessionIdCache"/>
Таким образом, он будет автоматически определять параметры конструктора.
Другой вариант - просто создать конструктор по умолчанию и свойство autowire gxSessionIdCache
.
Ответ 2
Вам нужно добавить пустой конструктор по умолчанию:
@Controller
public class CacheHandler {
private final CustomGxSessionIdCacheImpl gxSessionIdCache;
@Autowired
public CacheHandler(CustomGxSessionIdCacheImpl gxSessionIdCache) {
this.gxSessionIdCache = gxSessionIdCache;
}
Но будьте осторожны, потому что кажется, что вы смешиваете конфигурацию на основе аннотаций (@Controller) и конфигурацию XML. В приведенном выше примере он использует конфигурацию на основе аннотаций (поэтому, пожалуйста, удалите объявление bean из вашего XML файла).
Ответ 3
Вы также можете получить эту ошибку, если вы не активировали конфигурацию на основе аннотаций Spring. Включите это в свой Spring Xml:
< контекст: аннотация-конфигурация/ >
Ответ 4
Другие плакаты указали, что вы можете столкнуться с проблемами, если вы смешиваете автообновление/компонентное сканирование с явным экземпляром beans. У меня была аналогичная проблема с веб-приложением, которое это сделало. Я смог устранить проблему, сообщив компонентному сканеру, чтобы он не автоматически создавал bean ключевого класса. Вот так:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=...>
<aop:aspectj-autoproxy />
<import resource="repository.xml" />
...
<context:component-scan base-package="com.example.webserver">
<context:exclude-filter type="regex" expression="MyRepositoryImpl" />
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" />
</context:component-scan>
</beans>
где repository.xml
включено явное bean:
<beans xmlns=...>
<bean id="password" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:/comp/env/store/clientPassword" />
</bean>
<bean id="repository" class="com.example.webserver.datalayer.MyRepositoryImpl">
<constructor-arg ref="password" />
</bean>
...
</beans>