2011-06-17 26 views
5

Tengo una aplicación donde se utiliza un marcador de posición propiedad para leer las propiedades, configurado en applicationContext.xml:Añadir propiedades de marcador de posición propiedad

... 
<context:property-placeholder 
    location="classpath*:META-INF/spring/*.properties"/> 
... 

La aplicación se ejecuta en un Tomcat y utiliza el parámetro definido en context.xml. La aplicación accede a este parámetro como propiedades normales (@Value(${cfma.applicationUrl})). Esto funciona

En mis casos de prueba, no tengo estas propiedades de tomcat, por lo que quiero agregarlas "manualmente" al contexto de la aplicación. Pero también cargar la normalidad applicationContext.xml

testContext.xml:

<import resource="classpath:/META-INF/spring/applicationContext.xml" /> 
<context:property-placeholder properties-ref="simulatedTomcatProperties"/> 
<util:properties id="simulatedTomcatProperties"> 
    <prop key="cfmt.applicationBaseUrl">localhost:8080/cfmt</prop> 
</util:properties> 

Ahora tengo dos contexto: la propiedad del marcador de posición y esto no funciona (por supuesto) - Así que mi pregunta es, que puedo extender las propiedades en la propiedad "normal"-marcador de posición en mi prueba?


Más explicación de lo que necesito:

  • el entorno productivo (así como el entorno de desarrollo) define algunas propiedades mediante el parámetro Tomcat. Por lo tanto, no están incluidos en ningún archivo de propiedades, pero pueden acceder a ellos como propiedades normales (@Value(${cfma.applicationUrl})). Además, no debe haber ninguna Devolución, si las propiedades no están definidas en el Tomcat, ¡la aplicación no debe comenzar!
  • En los casos de prueba (que utilizan el contexto de primavera) Debo algunos cómo insertar la propiedad (cfma.applicationUrl) de modo que se puede inyectar en las variables anotadas. Pero si añado una segunda context:property-placeholder que no se fusionan:

@see Comentarios sobre https://jira.springsource.org/browse/SPR-4881 - explican ese comportamiento.


Cuando hablo de parámetro Tomcat que estoy hablando somethink así:

context.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<Context> 
    <WatchedResource>WEB-INF/web.xml</WatchedResource> 
    <Parameter name="cfmt.applicationBaseUrl" 
      value="http://localhost/demoApp" override="false"/> 
</Context> 
+0

Ver http://stackoverflow.com/questions/6375016/spring-properties-file-setting-default-values ​​Es efectivamente le permite definir múltiples ubicaciones de propiedades. Los archivos de propiedades perdidas se ignoran y se carga el último archivo válido de la lista. – Fil

+0

@Filip: Mi pregunta no es acerca de la ubicación múltiple. Me pegaron con múltiples configuradores de marcador de posición de propiedad. Y estoy buscando una forma de ampliar/cambiar la configuración del configurador de marcador de posición de propiedad de contexto de la aplicación "normal" desde mi test-context.xml – Ralph

+0

Lo siento. Mi comentario no era muy claro, no sugería una forma de especificar múltiples archivos de propiedades, sino una forma de hacer búsquedas de propiedades condicionales. Una respuesta expandida está abajo. – Fil

Respuesta

5

No estoy seguro si esto ayudará, pero lo que sí en una situación similar es tener 2 archivos app.properties con el mismo nombre, uno de cada seg/test/recursos y el otro en src/main/resources. Ahora, durante la prueba, el primero se carga porque las clases de prueba están primero en la ruta de clase, pero cuando despliegue solo la principal está allí y por lo tanto está cargada.

+0

Porque mi problema pertenece a propiedades adicionales mi solución es tener un archivo de propiedades adicional para mis pruebas en prueba/recursos (proyecto de bases Maven). – Ralph

+0

Sí, ¡termino duplicando propiedades en los dos archivos! –

3

¿Funciona si se agrega el mismo atributo location a la context:property-placeholder definido en testContext.xml que está en el definido en applicationContex.xml? También necesitaría agregar el atributo local-override="true" para tener el properties-ref anular los de META-INF.

Editar:

Dada su comentario más reciente, creo que tendrá que renunciar a utilizar el espacio de nombres context y directamente utilice los objetos muelle que se utiliza detrás de las escenas. Tal vez algo como esto:

En applicationContext.xml:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="location" value="classpath*:META-INF/spring/*.properties" /> 
</bean> 

En TestContext.xml:

<bean id="propertyConfigurerTest" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" parent="propertyConfigurer"> 
    <property name="properties" ref="simulatedTomcatProperties" /> 
    <property name="localOverride" value="true" /> 
</bean> 
<util:properties id="simulatedTomcatProperties"> 
    <prop key="cfmt.applicationBaseUrl">localhost:8080/cfmt</prop> 
</util:properties> 

supongo desea que las propiedades locales para anular las características que se determinan a partir de los recursos de ruta de clases por lo que he definido como verdadero localOverride.

+0

no desafortunadamente esto no ayuda. Me va como lo entendí, el problema es que si tengo dos definiciones 'context: property-placeholder' también tengo que titular de posición de propiedad, y no se fusionan. – Ralph

+0

Esperaría que el que está en 'testContext.xml' anule el de' applicationContext.xml' si se carga 2nd.¿Cuál es el comportamiento incorrecto que estás viendo? – laz

+0

No es incorrecto, se espera (que no funcione con dos contextos: propiedad-marcador de posición). El comportamiento es que el campo anotado @Value ($ {cfma.applicationUrl}) no se rellena en las pruebas. - Estoy buscando una forma de "extender" el marcador de posición de la propiedad desde applicationContex.xml en mi testContext.xml. – Ralph

3

Si, en su applicationContext.xml principal, especifica varias búsquedas de propiedades como se detalla a continuación utilizando un PropertiesFactoryBean, no se cargan los archivos de propiedades perdidas y se utiliza el último archivo de propiedades cargado con éxito. En su caso, se cargarían las propiedades predeterminadas (por ejemplo, el archivo de propiedades de prueba) y, dado que el segundo archivo: $ {catalina} ... no se cargaría, sus campos @Value se inyectarían con los valores especificados por defecto. propiedades.

respuesta tomado de here:

<bean id="myProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> 
    <property name="ignoreResourceNotFound" value="true" /> 
    <property name="locations"> 
     <list> 
     <value>classpath:default.properties</value> 
     <value>file:${catalina.home}/webapps/myProperties.properties</value> 
     </list> 
    </property> 
</bean> 
+0

Entonces la diferencia de su sugerencia y '' no es tanto. - Al menos sugieres tener un archivo de propiedades adicional para las pruebas, ¿no? – Ralph

+0

Exactamente. Y también podría extender PropertiesFactoryBean para que se ajuste más a sus necesidades; Lo uso para ayudarme a cargar diferentes archivos de configuración dependiendo de lo que estoy haciendo (por ejemplo, usando JNDI para búsquedas, o usando una base de datos H2 local, siembra con DBUnit, etc ...) – Fil

1

He resuelto el problema mediante la división de la applicationContext.xml en dos archivos: - applicationContext.xml - contiene el grano "normal", pero no se incluyen de applicationContext-properties.xml - applicationContext-properties.xml - contiene el marcador de posición config propiedad

applicationContext-properties.xml:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> 
     <property name="locations" value="classpath*:META-INF/spring/*.properties" /> 
     <property name="ignoreUnresolvablePlaceholders" value="false" /> 
</bean> 

Las cargas de aplicaciones web ambos archivos en el arranque:

web.xml:

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value> 
</context-param> 

Para mis pruebas he añadido un archivo propoperties: simulatedTomcat.test-properties que contiene todas las propiedades Tomcat. nota: que este archivo no coincide con el patrón usado por las propiedades de marcador de posición configurador de applicationContext-properties.xml

entonces tengo una propiedades marcador de posición configurador para mi prueba de que la carga tanto en especie archivos de propiedades op (*.properties y *.test-properties)

test-context.xml

<import resource="classpath:/META-INF/spring/applicationContext.xml" /> 
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"> 
    <property name="locations"> 
     <list> 
     <value>classpath*:META-INF/spring/*.properties</value> 
     <value>classpath*:META-INF/spring/*.test-properties</value> 
     </list> 
    </property> 
</bean> 
Cuestiones relacionadas