inicializar example contexto configuracion bean java spring configuration

java - example - Archivo de configuración de Import Spring basado en la propiedad en el archivo.properties



spring configuracion (10)

Agregue algo similar a lo siguiente:

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="ignoreResourceNotFound"><value>true</value></property> <property name="locations"> <list> <value>classpath:propertyfile.properties</value> </list> </property> </bean>

En mi configuración de Spring xml estoy tratando de hacer que algo como esto funcione:

<beans> <import resource="${file.to.import}" /> <!-- Other bean definitions --> </beans>

Quiero decidir qué archivo importar según una propiedad en un archivo de propiedades. Sé que puedo usar una propiedad del sistema, pero no puedo agregar una propiedad a la JVM al inicio.

Nota: PropertyPlaceHolderConfigurer no funcionará. Las importaciones se resuelven antes de ejecutar cualquier BeanFactoryPostProcessors. El elemento de importación solo puede resolver System.properties.

¿Alguien tiene una solución simple para esto? No quiero comenzar a subclasificar clases de framework, etc.

Gracias


Desafortunadamente, esto es mucho más difícil de lo que debería ser. En mi aplicación lo logré haciendo lo siguiente:

  1. Un contexto pequeño, "bootstrap", que es responsable de cargar un bean PropertyPlaceholderConfigurer y otro bean que se encarga de iniciar el contexto de la aplicación.

  2. El segundo bean mencionado anteriormente toma como entrada los archivos de contexto de primavera "reales" para cargar. Tengo mis archivos de contexto de primavera organizados para que la parte configurable sea conocida y esté en el mismo lugar. Por ejemplo, podría tener 3 archivos de configuración: one.onpremise.xml, one.hosted.xml, one.multitenant.xml. El bean carga programáticamente estos archivos de contexto en el contexto de la aplicación actual.

Esto funciona porque los archivos de contexto se especifican como entrada del bean responsable de cargarlos. No funcionará si solo intenta hacer una importación, como mencionó, pero esto tiene el mismo efecto con un poco más de trabajo. La clase de arranque se parece a esto:

public class Bootstrapper implements ApplicationContextAware, InitializingBean { private WebApplicationContext context; private String[] configLocations; private String[] testConfigLocations; private boolean loadTestConfigurations; public void setConfigLocations(final String[] configLocations) { this.configLocations = configLocations; } public void setTestConfigLocations(final String[] testConfigLocations) { this.testConfigLocations = testConfigLocations; } public void setLoadTestConfigurations(final boolean loadTestConfigurations) { this.loadTestConfigurations = loadTestConfigurations; } @Override public void setApplicationContext(final ApplicationContext applicationContext) throws BeansException { context = (WebApplicationContext) applicationContext; } @Override public void afterPropertiesSet() throws Exception { String[] configsToLoad = configLocations; if (loadTestConfigurations) { configsToLoad = new String[configLocations.length + testConfigLocations.length]; arraycopy(configLocations, 0, configsToLoad, 0, configLocations.length); arraycopy(testConfigLocations, 0, configsToLoad, configLocations.length, testConfigLocations.length); } context.setConfigLocations(configsToLoad); context.refresh(); } }

Básicamente, obtenga el contexto de la aplicación, establezca sus ubicaciones de configuración y dígale que se actualice. Esto funciona perfectamente en mi aplicación.

Espero que esto ayude.


Estoy usando Spring 3 y cargo propiedades como las siguientes:

<context:property-placeholder location="/WEB-INF/my.properties" />


Hay un problema antiguo en Spring JIRA para agregar propiedades de soporte de marcador de posición para la importación (SPR-1358) que se resolvió como "No se soluciona", pero desde entonces se ha presentado una solución propuesta con un EagerPropertyPlaceholderConfigurer.

He estado presionando para que se haya reabierto la SPR-1358, pero hasta ahora no hubo respuesta. Quizás, si otros agregaran sus casos de uso al tema, comentarios que ayudarían a crear conciencia.


La respuesta de André Schuster, que superé, me ayudó a resolver un problema muy similar que tenía al querer encontrar una expresión de propiedades diferente dependiendo de si estaba ejecutando mi propio host, de Jenkins en nuestro host de compilación o en una implementación "real". . Hice esto:

<context:property-placeholder location="file:///etc/myplace/database.properties" />

seguido más tarde por

<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>WEB-INF/classes/resources/database.properties</value> ... </list> </property> </bean>

que resolvió mi problema porque en mi host de desarrollo, puse un enlace a mi propia copia de database.properties en /etc/myplace/database.properties , y una ligeramente diferente en el servidor que ejecuta Jenkins. En la implementación real, no se encuentra ese archivo, por lo que Spring vuelve a caer en el "verdadero" en los recursos en mi subdirectorio de archivos de clase. Si las propiedades en cuestión ya han sido especificadas por el archivo en /etc/myplace/database.properties , entonces (afortunadamente) no son redefinidas por el archivo local.


Otra solución que no depende de las propiedades del sistema es cargar las propiedades de todos los archivos utilizando un PropertyPlaceholderConfigurer diferente para cada archivo y definir un Prefix de marcador de posición diferente para cada uno de ellos. Ese placeholderprefix está configurado por el archivo de propiedades inicial.


Defina el primer archivo de propiedad: (que contiene el primero o el segundo)

global.properties

fileToUse=first


Defina los archivos que contienen una propiedad que se puede cambiar dependiendo de la propiedad definida anteriormente:

first.properties

aProperty=propertyContentOfFirst

second.properties

aProperty=propertyContentOfSecond


Luego defina los marcadores de lugar para todos los archivos:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:global.properties</value> </list> </property> </bean> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="placeholderPrefix" value="first{" /> <property name="locations"> <list> <value>classpath:first.properties</value> </list> </property> </bean> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="placeholderPrefix" value="second{" /> <property name="locations"> <list> <value>classpath:second.properties</value> </list> </property> </bean>


Use la propiedad definida en global para identificar el recurso a usar del otro archivo:

${fileToUse}{aProperty}



Por qué no:

  1. lea su archivo de propiedades al inicio
  2. eso determinará qué configuración de Spring cargar
  3. cualquiera que sea la configuración de Spring cargada establece cosas específicas, luego carga una configuración Spring común

por lo que efectivamente está invirtiendo su solución propuesta actual.


Si agrego el argumento JVM a continuación y tengo el archivo myApplicationContext.dev.xml, la primavera se carga

-DmyEnvironment = dev

<context:property-placeholder /> <import resource="classpath:/resources/spring/myApplicationContext.${myEnvironment}.xml"/>


Si lo que desea es especificar el nombre de archivo XML importado fuera de applicationContext.xml para poder reemplazar applicationContext.xml sin perder la configuración de la ruta del archivo XML importado, puede simplemente agregar un archivo XML de Spring Beans intermedio, por ejemplo, confSelector. xml, por lo que applicationContext.xml importa confSelector.xml y confSelector.xml solo contiene un elemento <import> que hace referencia al archivo XML de beans personalizados adecuado.

Otro medio que podría ser de utilidad son las entidades XML (definidas al agregar elementos <! ENTITY ...> en la declaración DTD al comienzo de XML). Éstos permiten importar fragmentos XML de otros archivos y proporcionar funcionalidad tipo "marcador de posición de propiedad" para cualquier archivo XML.

Sin embargo, ninguna de estas soluciones le permite tener el archivo de configuración en formato .properties de Java.