Tengo varios archivos de propiedades que quiero cargar desde classpath. Hay un conjunto predeterminado en el /src/main/resources
que forma parte myapp.jar
. Mi springcontext
espera que los archivos estén en el classpath. es decir
<util:properties id="Job1Props"
location="classpath:job1.properties"></util:properties>
<util:properties id="Job2Props"
location="classpath:job2.properties"></util:properties>
También necesito la opción de anular estas propiedades con un conjunto externo. Tengo una carpeta de configuración externa en cwd
. Según la carpeta de configuración de Spring boot doc debe estar en classpath. Pero no está claro en el documento si solo anulará elapplicaiton.properties
desde allí o todas las propiedades en la configuración.
Cuando lo probé, solo application.properties
se recogen y el resto de las propiedades aún se recogen /src/main/resources
. He intentado suministrarlos como una lista separada por comas aspring.config.location
pero el conjunto predeterminado todavía no se anula.
¿Cómo hago que varios archivos de configuración externos anulen los predeterminados?
Como solución, actualmente utilizo app.config.location
(propiedad específica de la aplicación) que proporciono a través de la línea de comando. es decir
java -jar myapp.jar app.config.location=file:./config
y cambié mi applicationcontext
a
<util:properties id="Job2Props"
location="{app.config.location}/job2.properties"></util:properties>
Y así es como hago la separación entre el archivo y classpath al cargar la aplicación.
EDICIONES:
//psuedo code
if (StringUtils.isBlank(app.config.location)) {
System.setProperty(APP_CONFIG_LOCATION, "classpath:");
}
Realmente me gustaría no usar la solución anterior y hacer que Spring anule todos los archivos de configuración externos en el classpath como lo hace para el application.properties
archivo.
application.properties
siempre se cargará, conspring.config.location
usted puede agregar ubicaciones adicionales de configuración que se comprueban los archivos (que es cuando termina con una/
), sin embargo si se pone una coma separados ahí que apunta a los archivos de los que se cargará. Esto también se explica en la Guía de referencia de Spring Boot aquíRespuestas:
Cuando se utiliza Spring Boot, las propiedades se cargan en el siguiente orden (consulte Configuración externalizada en la guía de referencia de Spring Boot).
Al resolver propiedades (es decir, la
@Value("${myprop}")
resolución se realiza en el orden inverso (comenzando con 9).Para agregar diferentes archivos, puede usar las
spring.config.location
propiedades que toman una lista separada por comas de archivos de propiedades o ubicación de archivos (directorios).El anterior agregará un directorio que se consultará para los
application.properties
archivos.Esto agregará el archivo de 2 propiedades a los archivos que se cargan.
Los archivos y ubicaciones de configuración predeterminados se cargan antes que los especificados adicionalmente
spring.config.location
, lo que significa que este último siempre anulará las propiedades establecidas en los anteriores. (Consulte también esta sección de la Guía de referencia de Spring Boot).ACTUALIZACIÓN: como el comportamiento de spring.config.location ahora anula el valor predeterminado en lugar de agregarlo. Debe usar spring.config.additional-location para mantener los valores predeterminados. Este es un cambio en el comportamiento de 1.xa 2.x
fuente
application.properties
yapplication-[env].properties
. No tiene en cuenta otros archivos de propiedades. Esto también se indica en la guía de referencia (en la sección a la que conduce el enlace y la cita de la guía de referencia).config.location
econfig.names
interactuar, aunque probablemente parezca claro para las personas que ya saben cómo interactúan. ¿Puedes actualizar tu respuesta para agregar algo a la documentación?spring.config.location
ahora anula el valor predeterminado en lugar de agregarlo. Debe usarspring.config.additional-location
para mantener los valores predeterminados. Este es un cambio de comportamiento de 1.xa 2.x.Con Spring boot, spring.config.location funciona, solo proporciona archivos de propiedades separados por comas.
ver el siguiente código
uno puede poner la versión predeterminada de jdbc.properties dentro de la aplicación. Las versiones externas se pueden configurar mentira esto.
Según el valor del perfil establecido con la propiedad spring.profiles.active, se recogerá el valor de jdbc.host. Entonces cuando (en windows)
jdbc.host tomará valor de jdbc-dev.properties.
para
jdbc.host tomará valor de jdbc.properties.
fuente
Spring boot 1.X y Spring Boot 2.X no proporcionan las mismas opciones y comportamiento sobre el
Externalized Configuration
.La muy buena respuesta de M. Deinum se refiere a las especificaciones de Spring Boot 1.
Actualizaré para Spring Boot 2 aquí.
Fuentes de propiedades ambientales y orden
Spring Boot 2 usa un
PropertySource
orden muy particular que está diseñado para permitir una anulación sensata de los valores. Las propiedades se consideran en el siguiente orden:Para especificar archivos de propiedades externas, estas opciones deberían interesarle:
Puede usar solo una de estas 3 opciones o combinarlas según sus requisitos.
Por ejemplo, para casos muy simples, usar solo propiedades específicas de perfil es suficiente, pero en otros casos es posible que desee usar propiedades específicas de perfil, propiedades predeterminadas y
@PropertySource
.Ubicaciones predeterminadas para los archivos application.properties
Acerca de los
application.properties
archivos (y variantes), Spring los carga de forma predeterminada y agrega sus propiedades en el entorno a partir de estos en el siguiente orden:Las prioridades más altas son tan literalmente:
classpath:/,classpath:/config/,file:./,file:./config/
.¿Cómo usar archivos de propiedades con nombres específicos?
Las ubicaciones predeterminadas no siempre son suficientes: las ubicaciones predeterminadas como el nombre de archivo predeterminado (
application.properties
) pueden no ser adecuadas. Además, como en la pregunta de OP, es posible que deba especificar varios archivos de configuración distintos deapplication.properties
(y variante).Entonces
spring.config.name
no será suficiente.En este caso, debe proporcionar una ubicación explícita utilizando la
spring.config.location
propiedad del entorno (que es una lista separada por comas de ubicaciones de directorio o rutas de archivos).Para ser libre sobre el patrón de nombres de archivo, favorezca la lista de rutas de archivos sobre la lista de directorios.
Por ejemplo hacer así:
Esa manera es la más detallada que solo especificando la carpeta, pero también es la forma de especificar muy finamente nuestros archivos de configuración y documentar claramente las propiedades efectivamente utilizadas.
spring.config.location ahora reemplaza las ubicaciones predeterminadas en lugar de agregarlas
Con Spring Boot 1, el
spring.config.location
argumento agrega ubicaciones específicas en el entorno Spring.Pero desde Spring Boot 2,
spring.config.location
reemplaza las ubicaciones predeterminadas utilizadas por Spring por las ubicaciones especificadas en el entorno de Spring como se indica en la documentación .spring.config.location
ahora es una forma de asegurarse de que cualquierapplication.properties
archivo tenga que especificarse explícitamente.Para los JAR súper que no deben empaquetar
application.properties
archivos, eso es bastante bueno.Para mantener el viejo comportamiento de
spring.config.location
Spring Boot 2, puede usar la nuevaspring.config.additional-location
propiedad en lugar despring.config.location
que todavía agregue las ubicaciones como se indica en la documentación :En la práctica
Supongamos que, como en la pregunta OP, tiene que especificar 2 archivos de propiedades externas y 1 archivo de propiedades incluido en el uber jar.
Para usar solo los archivos de configuración que especificó:
Para agregar archivos de configuración a estos en las ubicaciones predeterminadas:
classpath:/applications.properties
en el último ejemplo no es obligatorio ya que las ubicaciones predeterminadas tienen eso y las ubicaciones predeterminadas aquí no se sobrescriben sino que se extienden.fuente
application.properties
con todos los parámetros y múltiples${file_name}.properties
con conjuntos de propiedades definidos parcialmente. Por lo tanto, si usa@PropertySource
u otros enlaces fuertes a archivos, puede crear otro archivo externo y anular esas propiedades (por ejemplo: desdeclasspath:file.properties
).Eche un vistazo al PropertyPlaceholderConfigurer, me parece más fácil de usar que la anotación.
p.ej
fuente
este es un enfoque simple usando el arranque de primavera
TestClass.java
el contexto de app.properties , en la ubicación seleccionada
su aplicación de arranque de primavera
y el contexto predefinido application.properties
puede escribir tantas clases de configuración como desee y habilitarlas / deshabilitarlas simplemente configurando spring.profiles.active = el nombre / nombres del perfil {separados por comas}
como puede ver, el arranque de primavera es excelente, solo necesita algún tiempo para familiarizarse, vale la pena mencionar que también puede usar @Value en sus campos
fuente
Yo tuve el mismo problema. Quería tener la capacidad de sobrescribir un archivo de configuración interna en el inicio con un archivo externo, similar a la detección de Spring Boot application.properties. En mi caso, es un archivo user.properties donde se almacenan los usuarios de mis aplicaciones.
Mis requisitos:
Cargue el archivo desde las siguientes ubicaciones (en este orden)
Se me ocurrió la siguiente solución:
Ahora la aplicación usa el recurso classpath, pero también busca un recurso en las otras ubicaciones dadas. El último recurso que existe será elegido y utilizado. Puedo iniciar mi aplicación con java -jar myapp.jar --properties.location = / directory / myproperties.properties para usar una ubicación de propiedades que flota mi barco.
Un detalle importante aquí: utilice una cadena vacía como valor predeterminado para la ubicación de propiedades en la anotación @Value para evitar errores cuando no se establece la propiedad.
La convención para una ubicación de propiedades es: Use un directorio o una ruta a un archivo de propiedades como propiedades.ubicación.
Si desea anular solo propiedades específicas, se puede usar un PropertiesFactoryBean con setIgnoreResourceNotFound (true) con la matriz de recursos establecida como ubicaciones.
Estoy seguro de que esta solución se puede extender para manejar múltiples archivos ...
EDITAR
Aquí mi solución para múltiples archivos :) Como antes, esto se puede combinar con un PropertiesFactoryBean.
fuente
Spring Boot nos permite escribir diferentes perfiles para escribir para diferentes entornos, por ejemplo, podemos tener archivos de propiedades separados para entornos de producción, qa y locales
El archivo application-local.properties con configuraciones de acuerdo con mi máquina local es
Del mismo modo, podemos escribir application-prod.properties y application-qa.properties tantos archivos de propiedades como queramos
luego escriba algunos scripts para iniciar la aplicación para diferentes entornos, por ejemplo
fuente
Acabo de tener un problema similar a esto y finalmente descubrí la causa: el archivo application.properties tenía los atributos de propiedad y rwx incorrectos. Entonces, cuando Tomcat inició el archivo application.properties estaba en la ubicación correcta, pero era propiedad de otro usuario:
fuente
Una versión modificada de la solución @mxsb que nos permite definir múltiples archivos y en mi caso estos son archivos yml.
En mi aplicación-dev.yml, agregué esta configuración que me permite inyectar todos los yml que tienen -dev.yml en ellos. Esta puede ser una lista de archivos específicos también. "classpath: /test/test.yml,classpath: /test2/test.yml"
Esto ayuda a obtener un mapa de propiedades.
Sin embargo, si como en mi caso, quisiera tener que dividir los archivos yml para cada perfil y cargarlos e inyectarlos directamente en la configuración del resorte antes de la inicialización de los beans.
... tienes la idea
El componente es ligeramente diferente.
}
fuente
Si desea anular los valores especificados en su archivo application.properties, puede cambiar su perfil activo mientras ejecuta su aplicación y crea un archivo de propiedades de la aplicación para el perfil. Entonces, por ejemplo, especifiquemos el perfil activo "anular" y luego, suponiendo que haya creado su nuevo archivo de propiedades de la aplicación llamado "application-override.properties" en / tmp, puede ejecutar
Los valores especificados en spring.config.location se evalúan en orden inverso. Entonces, en mi ejemplo, primero se evalúa el classpat, luego el valor del archivo.
Si el archivo jar y el archivo "application-override.properties" están en el directorio actual, puede simplemente usar
ya que Spring Boot encontrará el archivo de propiedades por ti
fuente
He encontrado que este es un patrón útil a seguir:
Aquí anulamos el uso de "application.yml" para usar "application-MyTest_LowerImportance.yml" y también "application-MyTest_MostImportant.yml"
(Spring también buscará archivos .properties)
También se incluye como una bonificación adicional la configuración de depuración y rastreo, en una línea separada para que pueda comentarlos si es necesario;]
La depuración / rastreo es increíblemente útil ya que Spring volcará los nombres de todos los archivos que carga y los que intenta cargar.
Verá líneas como esta en la consola en tiempo de ejecución:
fuente
Me encontré con muchos problemas al tratar de resolver esto. He aquí mi arreglo,
Dev Env: Windows 10, Java: 1.8.0_25, Spring Boot: 2.0.3.RELEASE, Spring: 5.0.7.RELEASE
Lo que encontré es que Spring está apegado al concepto "Valores predeterminados sensibles para la configuración". Esto se traduce en que debes tener todos tus archivos de propiedad como parte de tu archivo de guerra. Una vez allí, puede anularlos utilizando la propiedad de línea de comando "--spring.config.additional-location" para apuntar a archivos de propiedades externas. Pero esto NO FUNCIONARÁ si los archivos de propiedades no son parte del archivo de guerra original.
Código de demostración: https://github.com/gselvara/spring-boot-property-demo/tree/master
fuente