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

infomapa dentroMapBindingSamplepor alguna razón (tal vez porque se está utilizando para ejecutar la aplicación en laSpringApplication.runllamada).info.buildlugar deinfodesde el mapa anterior?locations(obtener las propiedades de otroymlarchivo 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=123conjunto de propiedades del sistema, el ejemplo que dio en la respuesta volveríaversion=123, mientras que después de establecerlolocationsvolverí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
@Beanmétodo anotado.application.yml:
SomeComponent.java:
Podemos club tanto con
@Valueanotaciones como@ConfigurationPropertiessin problemas. Pero los captadores y los setters son importantes y@EnableConfigurationPropertieses imprescindible tener la@ConfigurationPropertiescapacidad para funcionar.Probé esta idea de la maravillosa solución proporcionada por @Szymon Stepniak, pensé que sería útil para alguien.
fuente
@EnableConfigurationPropertiesHoy 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:providersmap 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
providersmapaOAuth2ProvidersServiceno se inicializó. Probé la solución sugerida por Andy, pero no funcionó tan bien. Yo uso Groovy en esa aplicación, así que decidí eliminarprivatey 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
privatey proporcionar al setter un tipo de argumento directo en el método setter. Desafortunadamente, eso no funcionará. Causaorg.springframework.beans.NotWritablePropertyExceptioncon 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