Inyectar un mapa desde un archivo YAML con Spring

1. Información general

En este tutorial rápido, veremos de cerca cómo inyectar un mapa desde un archivo YAML en Spring Boot .

Primero, comenzaremos con un poco de información sobre los archivos YAML en Spring Framework. Luego, mostraremos, a través de un ejemplo práctico, cómo vincular propiedades YAML a un mapa .

2. Archivos YAML en Spring Framework

El uso de archivos YAML para almacenar datos de configuración externos es una práctica común entre los desarrolladores de Spring. Básicamente, Spring admite documentos YAML como una alternativa a las propiedades y usa SnakeYAML bajo el capó para analizarlos .

Sin más preámbulos, veamos cómo se ve un archivo YAML típico:

server: port: 8090 application: name: myapplication url: //myapplication.com

Como podemos ver, el archivo YAML es autoexplicativo y más legible por humanos. De hecho, YAML proporciona una forma elegante y concisa de almacenar datos de configuración jerárquica.

De forma predeterminada, Spring Boot lee las propiedades de configuración de application.properties o application.yml al inicio de la aplicación. Sin embargo, podemos usar @PropertySource para cargar un archivo YAML personalizado.

Ahora que estamos familiarizados con lo que es un archivo YAML, veamos cómo inyectar propiedades YAML como un mapa en Spring Boot.

3. Cómo inyectar un mapa desde un archivo YAML

Spring Boot ha llevado la externalización de datos al siguiente nivel al proporcionar una práctica anotación llamada @ConfigurationProperties. Esta anotación se introduce para inyectar fácilmente propiedades externas de archivos de configuración directamente en objetos Java .

En esta sección, cubriremos en profundidad cómo vincular propiedades YAML en una clase de bean usando la anotación @ConfigurationProperties .

Primero, definamos algunas propiedades de valor-clave en application.yml :

server: application: name: InjectMapFromYAML url: //injectmapfromyaml.dev description: How To Inject a map from a YAML File in Spring Boot config: ips: - 10.10.10.10 - 10.10.10.11 - 10.10.10.12 - 10.10.10.13 filesystem: - /dev/root - /dev/md2 - /dev/md4 users: root: username: root password: rootpass guest: username: guest password: guestpass

En este ejemplo, intentaremos mapear la aplicación en un mapa simple . Del mismo modo, inyectaremos detalles de configuración como un mapa , y los usuarios como un mapa con claves de cadena y objetos que pertenecen a una clase definida por el usuario - Credencial - como valores .

En segundo lugar, creemos una clase de bean, ServerProperties, para encapsular la lógica de vincular nuestras propiedades de configuración a Map s:

@Component @ConfigurationProperties(prefix = "server") public class ServerProperties { private Map application; private Map
    
      config; private Map users; // getters and setters public static class Credential { private String username; private String password; // getters and setters } }
    

Como podemos ver, decoramos la clase ServerProperties con @ConfigurationProperties. De esa manera, le decimos a Spring que asigne todas las propiedades con el prefijo especificado a un objeto de ServerProperties .

Recuerde que nuestra aplicación también debe estar habilitada para las propiedades de configuración, aunque esto se hace automáticamente en la mayoría de las aplicaciones Spring Boot.

Finalmente, probemos si nuestras propiedades YAML se inyectan correctamente como Map s:

@RunWith(SpringRunner.class) @SpringBootTest class MapFromYamlIntegrationTest { @Autowired private ServerProperties serverProperties; @Test public void whenYamlFileProvidedThenInjectSimpleMap() { assertThat(serverProperties.getApplication()) .containsOnlyKeys("name", "url", "description"); assertThat(serverProperties.getApplication() .get("name")).isEqualTo("InjectMapFromYAML"); } @Test public void whenYamlFileProvidedThenInjectComplexMap() { assertThat(serverProperties.getConfig()).hasSize(2); assertThat(serverProperties.getConfig() .get("ips") .get(0)).isEqualTo("10.10.10.10"); assertThat(serverProperties.getUsers() .get("root") .getUsername()).isEqualTo("root"); } }

4. @ConfigurationProperties vs @Value

Ahora hagamos una comparación rápida de @ConfigurationProperties y @Value.

A pesar de que ambas anotaciones se pueden usar para inyectar propiedades desde archivos de configuración , son bastante diferentes. La principal diferencia entre estas dos anotaciones es que cada una tiene un propósito diferente.

En resumen, @V alor nos permite inyectar directamente un valor de propiedad particular por su clave. Sin embargo, la anotación @ConfigurationProperties vincula varias propiedades a un objeto en particular y proporciona acceso a las propiedades a través del objeto mapeado.

En general, Spring recomienda usar @ConfigurationProperties sobre @Value cuando se trata de inyectar datos de configuración . @ConfigurationProperties ofrece una excelente manera de centralizar y agrupar propiedades de configuración en un objeto estructurado que luego podemos inyectar en otros beans.

5. Conclusión

Para resumir, primero explicamos cómo inyectar un mapa desde un archivo YAML en Spring Boot. Luego, resaltamos la diferencia entre @ConfigurationProperties y @Value.

Como de costumbre, el código fuente completo del artículo está disponible en GitHub.