2012-02-15 27 views
12

estoy teniendo problemas con mis controladores de primavera - que estoy recibiendo ningún constructor predeterminado encontró - pero tienen un constructor que estoy tratando de creado a través de la applicationContext.xml - aquí está el bit correspondiente:Spring MVC no se encuentra un constructor predeterminado?

<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> 

es decir. Primero estoy creando un bean y luego intento pasar el resultado de una llamada a un método desde ese bean al constructor del segundo bean (CacheHandler).

Here'e el inicio de CacheHandler:

@Controller 
    public class CacheHandler { 

    private final CustomGxSessionIdCacheImpl gxSessionIdCache; 

    public CacheHandler(CustomGxSessionIdCacheImpl gxSessionIdCache) { 
     this.gxSessionIdCache = gxSessionIdCache; 
    } 

Aquí está el error que estoy recibiendo:

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>() 

Cualquier ayuda es muy apreciada!

Respuesta

20

Debe definir sus beans en xml o anotarlos, no ambos (solo para evitar errores como el que está recibiendo).

El problema aquí es que no está autoarriendo args constructor, por lo que la primavera no sabe qué hacer con su controlador. Sabe que tiene que crear un bean (anotación @Controller), pero no sabe cómo hacerlo (no es un defecto, ni un constructor autocableado).

Usted puede tratar de hacer algo como:

@Controller 
public class CacheHandler { 

private final CustomGxSessionIdCacheImpl gxSessionIdCache; 

@Autowired 
public CacheHandler(CustomGxSessionIdCacheImpl gxSessionIdCache) { 
    this.gxSessionIdCache = gxSessionIdCache; 
} 

y luego en xml:

<bean id="gxSessionIdCache" 
    factory-bean="PcrfSimulator" 
    factory-method="getGxSessionIdCache"/> 

por lo que Autowire parámetros del constructor.

Otra opción es simplemente crear el constructor por defecto y autoconfigurar la propiedad gxSessionIdCache.

+0

compartimos la misma idea ;-) –

+0

Grandes, gracias por todas las respuestas! – Rory

+1

genial para confirmar esto, la primavera necesita un constructor predeterminado o un constructor con cable automático. – lwpro2

2

hay que añadir un constructor por defecto vacío:

@Controller 
    public class CacheHandler { 

    private final CustomGxSessionIdCacheImpl gxSessionIdCache; 

    @Autowired 
    public CacheHandler(CustomGxSessionIdCacheImpl gxSessionIdCache) { 
     this.gxSessionIdCache = gxSessionIdCache; 
    } 

Pero tenga cuidado, porque parece que usted está mezclando configuración basada en anotación (@Controller) y la configuración XML. En el ejemplo anterior, usa la configuración basada en anotaciones (por lo tanto, elimine la declaración de bean de su archivo XML).

+1

¿Por qué el constructor predeterminado? No es obligatorio ¿verdad? – kosa

+0

Acabo de editar mi publicación. –

+0

[¿Requiere Spring que todos los beans tengan un constructor predeterminado?] (Http://stackoverflow.com/questions/7492652/does-spring-require-all-beans-to-have-a-default-constructor): [* * no **] (http://stackoverflow.com/a/7492713/545127) – Raedwald

0

También puede obtener este error si no ha activado la configuración de Spring basada en anotaciones. Incluir esto en su XML de Spring:

< contexto: anotación-config/>

0

Otros críticos han señalado que se pueden tener problemas si se mezclan autowiring/componente de exploración con instancias explícita de los granos. Tuve un problema similar con una aplicación web que hizo eso. Pude solucionar el problema al decirle al componente-escáner que no instanciara automáticamente un bean de la clase crucial. De esta manera:

<?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> 

donde repository.xml incluyó la creación de instancias explícita de frijol:

<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> 
Cuestiones relacionadas