2011-12-21 9 views
8

Soy nuevo en Spring y heredé un proyecto de Spring que tenía toda la configuración XML en ProjectName/WebContent/WEB-INF/applicationContext.xml. Estoy tratando de dividir la configuración en diferentes componentes para que sea más fácil sustituir elementos como DataSources e Hibernate configuation cuando se prueban.No se puede importar el archivo de definición de Spring Bean usando la ruta relativa

Aquí es mi estructura de archivos:

ProjectName 
    ->WebContent 
     ->WEB-INF 
      ->applicationContext.xml 
      ->spring-datasource.xml 
      ->spring-hibernate-properties.xml 
      ->spring-persistence.xml 
    ->test 
     ->us.mn.k12... (Java pkgs with JUnit tests) 
     ->spring-hsqldb-datasource.xml 
     ->spring-test-bean-locations.xml 
     ->spring-test-hibernate-properties.xml 
    ->src 
     ->us.mn.k12... (Java pkgs with production code) 

en WEB-INF/applicationContext.xml, puedo importar lo siguiente:

<import resource="spring-datasource.xml"/> <!-- Production datasource --> 
<import resource="spring-hibernate-properties.xml"/> <!-- Production hibernate properties --> 
<import resource="spring-persistence.xml"/> <!-- DAO's, hibernate .hbm.xml mapping files --> 

La aplicación funciona con la configuración anterior.

Mis pruebas JUnit se ejecutan utilizando DbUnit y una base de datos en memoria HSQLDB. Así que mi referencias de prueba JUnit-pruebas de la primavera-frijol-locations.xml, que tiene la siguiente:

<import resource="spring-hsqldb-datasource.xml"/> <!-- HSQLDB datasource for test --> 
<import resource="../WebContent/WEB-INF/spring-persistence.xml"/> <!-- Production DAO's, hibernate .hbm.xml mapping files --> 
<import resource="spring-test-hibernate-properties.xml"/> <!-- Hibernate properties for test --> 

De esta manera, puedo especificar la fuente de datos de prueba y de hibernación propiedades, pero volver a utilizar el archivo de asignación de producción para la DAO de, etc. Sin embargo, me sale un error al ejecutar mi prueba JUnit. Aquí está la parte correspondiente de la excepción:

Caused by: org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from relative location [../WebContent/WEB-INF/spring-persistence.xml] 
Offending resource: class path resource [spring-test-bean-locations.xml]; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [../WebContent/WEB-INF/spring-persistence.xml]; nested exception is java.io.FileNotFoundException: class path resource [../WebContent/WEB-INF/spring-persistence.xml] cannot be opened because it does not exist 

Ahora si me mudo de primavera-persistence.xml en/test para que yo no tenga que utilizar la ruta relativa, y de referencia con <import resource="spring-persistence.xml"/>, a continuación, las pruebas corre bien Así que creo que el contenido de mis archivos XML está bien, pero no estoy importando correctamente con una ruta relativa.

¿Hay algo obvio que estoy haciendo mal con mi importación de la ruta relativa? Y tal vez la pregunta más importante es, ¿se ve esto como una estrategia razonable para dividir applicationContext.xml en componentes para facilitar la prueba?

Gracias!

Respuesta

18

El problema es que cualquier cosa dentro de WEB-INF no está disponible para el ClassLoader en una configuración de proyecto normal (y Spring utiliza el ClassLoader de forma predeterminada para acceder a los recursos). Hay algunos trucos para solucionar esto (como hacer referencia a los contextos que utilizan el prefijo file :,), pero esos son en su mayoría feos.

Una mejor práctica que sugiero es mover los archivos de contexto fuera de WEB-INF y en un directorio de recursos dedicado (src/main/resources si tiene una configuración de experto). De esta forma estarán disponibles tanto para el ClassLoader webapp como para los ClassLoaders de prueba de unidades locales.

Lea el artículo resources chapter para comprender mejor los mecanismos implicados.

+1

Gracias por la explicación Sean. Estamos usando Ant y solo tenemos src, test y WebContent/WEB-INF como los 3 nodos en la raíz de nuestro proyecto. ¿Poner los archivos Spring xml de producción en el directorio src, y la prueba Spring xml en el directorio de prueba será una configuración típica? O son otras ubicaciones comúnmente utilizadas en una configuración que no es de Maven. ¡Gracias! – buck64

+0

@ buck64 sí, eso sería suficiente. En maven hay una convención para mantener las clases separadas de los recursos, pero para el cargador de clases es todo lo mismo. –

+0

si es así, ¿cómo puede ser posible que mis jarras (con frijoles) se coloquen en /applications/Foo.ear/FooWebApp?guerra/WEB-INF/lib y todo funciona! – voipp

11

Uso

<import resource="file:**/WebContent/WEB-INF/spring-persistence.xml" /> 

funciona en 3.2.1.RELEASE primavera. Las versiones anteriores no estoy seguro.

Cuestiones relacionadas