2010-11-30 23 views
8

Me encuentro usando dos beans idénticos en mi applicationContext.xml y mi applicationContext-test.xml. Me gustaría que mi contexto de prueba pueda heredarse del contexto de mi aplicación, para evitar repetirlo.Cómo declarar un contexto de aplicación principal

He visto un montón de material que indica que puede declarar un contexto de aplicación padre y beans de referencia de ese contexto, pero no puedo encontrar un ejemplo útil. ¿Alguien puede ayudar?

actualización Como algo de información de antecedentes, mi contexto normal de aplicación se carga en web.xml:

<context-param> 
    <description>Application Contexts for Spring</description> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/classes/applicationContext.xml</param-value> 
</context-param> 

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

Mi contexto de aplicación de prueba se carga en mis pruebas de unidad:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "/applicationContext-test.xml") 

Entonces digamos que tengo un frijol en mi contexto habitual:

<bean name="someBean" class="com.foo.MyClass" /> 

Luego, en el contexto de mi aplicación de prueba, me gustaría referirme a este bean. ¿Cómo lo hago?

actualización

Por sugerencia de skaffman, me he movido el grano en un archivo SharedBeans.xml e importado en mi applicationContext.xml. Sin embargo, esto provoca una excepción SAXParser:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Failed to import bean definitions from URL location [classpath:SharedBeans.xml] 
Offending resource: ServletContext resource [/WEB-INF/classes/applicationContext.xml]; nested exception is org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 1 in XML document from class path resource [SharedBeans.xml] is invalid; nested exception is org.xml.sax.SAXParseException: cvc-elt.1: Cannot find the declaration of element 'bean'. 
    at org.springframework.beans.factory.parsing.FailFastProblemReporter.error(FailFastProblemReporter.java:68) 

no puedo estar seguro de lo que estoy haciendo mal. El bean estaba funcionando bien en mi archivo de contexto, y todo lo que hice fue cortar y pegar en el nuevo archivo. Éstos son los contenidos de SharedBeans.xml en su totalidad:

<bean name="properties" class="com.foo.Properties"> 
    <constructor-arg><value>${module.name}</value></constructor-arg> 
    <constructor-arg><value>${businessUnit}</value></constructor-arg> 
    <constructor-arg><value>${product}</value></constructor-arg> 
    <constructor-arg><value>${env}</value></constructor-arg> 
    <constructor-arg><value>${machineName}</value></constructor-arg> 
    <constructor-arg><value>${collectionSet.company}</value></constructor-arg> 
    <constructor-arg><value>${route.tag}</value></constructor-arg> 
    <constructor-arg><value>${timeout}</value></constructor-arg>  
</bean> 
+1

Depende de cómo haya configurado las cosas. Por favor, da un ejemplo de tu uso de tus contextos. – skaffman

+0

@skaffman: Pregunta actualizada. Ejemplos apreciados – Samo

+2

Aún necesita el elemento de nivel superior '' .... – skaffman

Respuesta

5

Esto no me parece que sea un uso particularmente bueno de los casos para un contexto padre, que es útil sobre todo para establecer una jerarquía (por ejemplo, una de las raíces contexto de la aplicación web, contextos de múltiples servlets hijos).

Para su situación, será más simple y fácil de entender si solo extrae las definiciones de beans comunes en un archivo separado, y luego <import> en cada archivo de contexto que lo necesite. Usted podría hacer esto con contextos padre-hijo, pero va a ser más difícil de entender, innecesariamente.

OK, así que un ejemplo, poner su definición de frijol común en un archivo llamado shared-beans.xml, y ponerlo (por ahora) en el nivel superior de la ruta de clases, que contiene:

<bean name="someBean" class="com.foo.MyClass" /> 

Luego, en el interior applicationContext-test.xml y /WEB-INF/classes/applicationContext.xml, añada lo siguiente:

<import resource="classpath:/shared-beans.xml" /> 

todas las definiciones de frijol en shared-beans.xml a continuación, se importan en el contexto de cada aplicación. No obtiene un tercer contexto de la aplicación haciendo esto, solo importa las definiciones de bean de otro archivo.

+1

¿Podría aclarar por favor? Cuando dices "un archivo separado", ¿es esta una fábrica de frijoles? Si no, ¿qué es? Usted dice que puedo importarlos de este archivo, pero ¿puede proporcionar un ejemplo que demuestre cómo se hace? – Samo

+0

Recibo una excepción de SAXParser. Por favor vea la pregunta actualizada. No estoy seguro de lo que podría estar haciendo mal. – Samo

0

Puede mover su declaración común a un archivo XML por separado y colocarla en classpath (para un fácil acceso desde la prueba).A continuación, puede hacer lo siguiente:

<context-param> 
    <description>Application Contexts for Spring</description> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
     /WEB-INF/classes/applicationContext.xml 
     classpath:/common-beans.xml 
    </param-value> 
</context-param> 

.

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(
    locations = {"/applicationContext-test.xml", "common-beans.xml"}) 

También puede incluir common-beans.xml de ambos contextos utilizando <import>, como sugiere skaffman.

Cuestiones relacionadas