2012-01-19 21 views
19

Estoy trabajando en un proyecto con varios módulos separados, cada uno con sus propios archivos de propiedades de contexto de la aplicación. Quiero poder cargar todas estas propiedades para que Spring pueda usarlas para la resolución del marcador de posición.Archivos de propiedades múltiples en Spring 3.0

preguntas anteriores han mencionado esto y hay una buena entrada en el blog here que describe cómo utilizar un PropertyPlaceholderConfigurer en cada contexto, ordenarlas por prioridad y establece ignoreUnresolveablePlaceholders a true para que estos archivos de propiedades puede hacer una referencia cruzada entre sí sin soplar arriba.

Sin embargo, esto no resuelve mi problema ya que también quiero poder usar las propiedades que estoy cargando para alguna resolución de marcador de posición personalizada (de algunos archivos yaml que estoy analizando). Esto requiere el uso de un PropertyPlaceholderHelper, que requiere el objeto Properties como argumento.

Por lo que yo puedo decir, las posibles soluciones son:

1) archivo de combinación de todas las propiedades en un solo grano de propiedades. Esto puede ser usado para crear un PropertyPlaceholderConfigurer (para la resolución de marcador de posición interna de primavera) y se utiliza con un PropertyPlaceholderHelper (por mi propia resolución marcador de posición)

2) De alguna manera configurar un PropertyPlaceholderHelper utilizar el conjunto de propiedades, así como su disposición jerárquica, mantenida por PropertyPlaceholderConfigurers si continúo y sigo los consejos de esa publicación de blog.

Lamentablemente no puedo encontrar la forma de hacer cualquiera de estos. ¡Cualquier ayuda sería muy apreciada!

PD Parece que Spring 3.1 será de gran ayuda aquí ... lamentablemente todavía no estamos listos para pasar a eso, ¡así que todavía necesito una solución para superarme!

**** **** EDITAR

Gracias por las respuestas hasta el momento. Son buenas respuestas, pero desafortunadamente no me ayudarán porque (y me disculpo por no mencionar esto antes) estamos actualmente en el proceso de separar los módulos centrales de nuestro proyecto de los módulos no básicos. Esto significa que los módulos centrales y su contexto de aplicación no pueden codificar los nombres de los archivos de propiedades. Frustrante, el escaneo classpath de Spring parece estar roto, por lo que los comodines del tipo "classpath *: *. Properties" solo funcionan cuando se crean los módulos individuales, no el proyecto de nivel superior (creo que este es un problema conocido).

La pregunta es cómo fusionar los archivos de propiedades definidos en módulos no centrales en archivos de propiedades existentes definidos en módulos centrales. Por el momento estoy trabajando con un BeanPostProcessor. ¿Me pregunto si existe una forma más simple/más elegante de hacerlo?

Gracias

+0

Creo que debe proporcionar al menos un segmento dir constante, por lo que 'classpath *: *. Properties' no funcionará, pero' classpath *: config/*. Properties' lo hará. – mrembisz

Respuesta

7

siguiente fragmento de código servirán para iniciar

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="corePlaceHolder"> 
    <property name="ignoreUnresolvablePlaceholders" value="true"/> 
    <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/> 
    <property name="searchSystemEnvironment" value="true"/> 
    <property name="locations"> 
     <list> 
      <value>classpath*:config/*/config1/*.properties</value> 
      <value>classpath*:config/*/config2/*.properties</value> 
      <value>classpath*:config/*/config3/*.properties</value> 
      <value>classpath*:custom.properties</value> 
     </list> 
    </property> 
</bean>  

Es posible almacenar los archivos de propiedades en la siguiente jerarquía asegurándose de configuración es accesible desde a través de la ruta de clase

config 
    config1 
    a.properties 
    config2 
    b.properties 
    config3 
    c.properties 
custom.properties 
9

Puede recopilar múltiples archivos de propiedades en un bean con bastante facilidad:

<bean id="allProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean"> 
    <property name="singleton" value="true"/> 
    <property name="ignoreResourceNotFound" value="true"/> 
    <property name="locations"> 
    <list> 
     <value>classpath*:default.properties</value> 
     <value>classpath*:overrides.properties</value> 
     <value>file:${APP_HOME}/**/*.properties</value> 
    </list> 
    </property> 
</bean> 

Este ejemplo particular reunirá todas las propiedades predeterminadas, sobrescrituras.propiedades en classpath y archivos de propiedad en su APP_HOME. Ahora puede consultar este bean desde ProperyPlaceholderConfigurer o su postprocesador personalizado.

6

Esto es todo lo que tiene que hacer:

<context:property-placeholder location="first.properties" order="0" ignore-unresolvable="true"/> 
<context:property-placeholder location="second.properties" order="0" ignore-unresolvable="true"/> 
<context:property-placeholder location="empty.properties" order="1"/> 

El problema es simple: si una propiedad de marcador de posición no tiene valor para una determinada propiedad se lanzará una excepción, a pesar de que otras propiedades-marcador de posición están presentes .

La solución utiliza order saber que es el último property-placeholder y establece ignore-unresolvable="true" en todos los demás, de modo que cada property-placeholder tiene la oportunidad de proporcionar un valor. En proyectos de varios módulos, el último property-placeholder podría estar vacío o proporcionar valores predeterminados de falla.

Nota: si establece todos los bienes-marcador de posición a ignore-unresolvable="true" primavera acaba de transmitir lo que escribió sin lanzar una excepción. Si, por supuesto, espera que sea algo diferente a String, seguramente obtendrá una recepción como java.lang.NumberFormatException: For input string: "${something}" durante la conversión de formato.

Nota: sólo la primera (uno con menor order) property-placeholder con un valor para la propiedad específica se utilizará. Si desea anular las propiedades, use un rango mayor order que 0 y 1 o property-override.

Probado con Spring 3.2.1, pero todas las propiedades mencionadas existen en 3.0. Consulte JavaDoc of PropertyPlaceholderConfigurer

Cuestiones relacionadas