Tengo una aplicación Spring Boot con lo siguiente application.yml
, tomado básicamente de aquí :
info:
build:
artifact: ${project.artifactId}
name: ${project.name}
description: ${project.description}
version: ${project.version}
Puedo inyectar valores particulares, p. Ej.
@Value("${info.build.artifact}") String value
Sin embargo, me gustaría inyectar todo el mapa, es decir, algo como esto:
@Value("${info}") Map<String, Object> info
¿Es eso (o algo similar) posible? Obviamente, puedo cargar yaml directamente, pero me preguntaba si Spring ya admite algo.
java
spring
spring-boot
levant pied
fuente
fuente
info
mapa dentroMapBindingSample
por alguna razón (tal vez porque se está utilizando para ejecutar la aplicación en laSpringApplication.run
llamada).info.build
lugar deinfo
desde el mapa anterior?locations
(obtener las propiedades de otroyml
archivo en lugar de las predeterminadasapplication.yml
)@ConfigurationProperties
, funcionó, excepto que no resultó en el reemplazo de los marcadores de posición. Por ejemplo, si tuviera unproject.version=123
conjunto de propiedades del sistema, el ejemplo que dio en la respuesta volveríaversion=123
, mientras que después de establecerlolocations
volveríaproject.version=${project.version}
. ¿Sabes si hay algún tipo de limitación aquí?La siguiente solución es una abreviatura de la solución de @Andy Wilkinson, excepto que no tiene que usar una clase separada o un
@Bean
método anotado.application.yml:
SomeComponent.java:
Podemos club tanto con
@Value
anotaciones como@ConfigurationProperties
sin problemas. Pero los captadores y los setters son importantes y@EnableConfigurationProperties
es imprescindible tener la@ConfigurationProperties
capacidad para funcionar.Probé esta idea de la maravillosa solución proporcionada por @Szymon Stepniak, pensé que sería útil para alguien.
fuente
@EnableConfigurationProperties
Hoy me encuentro con el mismo problema, pero desafortunadamente la solución de Andy no funcionó para mí. En Spring Boot 1.2.1.RELEASE es aún más fácil, pero debes tener en cuenta algunas cosas.
Aquí está la parte interesante de mi
application.yml
:providers
map contiene solo una entrada de mapa, mi objetivo es proporcionar una configuración dinámica para otros proveedores de OAuth. Quiero inyectar este mapa en un servicio que inicializará los servicios según la configuración proporcionada en este archivo yaml. Mi implementación inicial fue:Después de iniciar la aplicación, el
providers
mapaOAuth2ProvidersService
no se inicializó. Probé la solución sugerida por Andy, pero no funcionó tan bien. Yo uso Groovy en esa aplicación, así que decidí eliminarprivate
y dejar que Groovy genere getter y setter. Entonces mi código se veía así:Después de ese pequeño cambio, todo funcionó.
Aunque hay una cosa que vale la pena mencionar. Después de hacerlo funcionar, decidí crear este campo
private
y proporcionar al setter un tipo de argumento directo en el método setter. Desafortunadamente, eso no funcionará. Causaorg.springframework.beans.NotWritablePropertyException
con mensaje:Téngalo en cuenta si está utilizando Groovy en su aplicación Spring Boot.
fuente
Para recuperar el mapa de la configuración, necesitará la clase de configuración. La anotación @Value no funcionará, desafortunadamente.
Application.yml
Clase de configuración:
fuente
Solución para extraer el mapa usando @Value de la propiedad application.yml codificada como multilínea
Aquí el valor de nuestra propiedad de mapa "my-map-property-name" se almacena en formato JSON dentro de una cadena y hemos obtenido varias líneas usando \ al final de la línea
Mas explicacion
\ en yaml se usa para dividir la cadena en varias líneas
\ " es el carácter de escape para" (cita) en la cadena yaml
{clave: valor} JSON en yaml que será convertido a mapa por @Value
# {} es expresión SpEL y se puede usar en @Value para convertir json int Map o Array / list Reference
Probado en un proyecto de arranque de primavera
fuente
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding
fuente
Puede hacerlo aún más simple, si desea evitar estructuras adicionales.
Y luego úselo como de costumbre, por ejemplo con un constructor:
fuente