Eu tenho um aplicativo Spring Boot com o seguinte application.yml
- tirado basicamente daqui :
info:
build:
artifact: ${project.artifactId}
name: ${project.name}
description: ${project.description}
version: ${project.version}
Posso injetar valores específicos, por exemplo
@Value("${info.build.artifact}") String value
Gostaria, no entanto, de injetar todo o mapa, ou seja, algo assim:
@Value("${info}") Map<String, Object> info
Isso (ou algo semelhante) é possível? Obviamente, posso carregar o yaml diretamente, mas gostaria de saber se há algo já suportado pelo Spring.
java
spring
spring-boot
Levant pied
fonte
fonte
info
mapa dentroMapBindingSample
por algum motivo (talvez porque ele está sendo usado para executar o aplicativo naSpringApplication.run
chamada).info.build
vez doinfo
mapa acima?locations
(para obter as propriedades de outroyml
arquivo em vez do padrãoapplication.yml
)@ConfigurationProperties
, funcionou, exceto que não resultou na substituição dos marcadores. Por exemplo, se você tivesse uma propriedade do sistemaproject.version=123
definida, o exemplo que você deu na resposta retornariaversion=123
, enquanto após a configuraçãolocations
retornariaproject.version=${project.version}
. Você sabe se há algum tipo de limitação aqui?A solução abaixo é um atalho para a solução de @Andy Wilkinson, exceto que ela não precisa usar uma classe separada ou em um
@Bean
método anotado.application.yml:
SomeComponent.java:
Podemos marcar
@Value
anotações e@ConfigurationProperties
sem problemas. Mas getters e setters são importantes e@EnableConfigurationProperties
devem@ConfigurationProperties
funcionar.Experimentei essa ideia com uma solução bacana fornecida por @Szymon Stepniak, achei que seria útil para alguém.
fonte
@EnableConfigurationProperties
Tive o mesmo problema hoje, mas infelizmente a solução de Andy não funcionou para mim. No Spring Boot 1.2.1.RELEASE é ainda mais fácil, mas você deve estar ciente de algumas coisas.
Aqui está a parte interessante do meu
application.yml
:providers
map contém apenas uma entrada de mapa, meu objetivo é fornecer configuração dinâmica para outros provedores OAuth. Quero injetar esse mapa em um serviço que inicializará serviços com base na configuração fornecida neste arquivo yaml. Minha implementação inicial foi:Depois de iniciar o aplicativo, o
providers
map inOAuth2ProvidersService
não foi inicializado. Tentei a solução sugerida por Andy, mas não funcionou tão bem. Eu uso o Groovy nesse aplicativo, então decidi removerprivate
e permitir que o Groovy gere getter e setter. Então, meu código era assim:Depois dessa pequena mudança, tudo funcionou.
Embora haja uma coisa que vale a pena mencionar. Depois de fazê-lo funcionar, decidi criar este campo
private
e fornecer ao setter o tipo de argumento direto no método setter. Infelizmente não vai funcionar assim. Isso causaorg.springframework.beans.NotWritablePropertyException
com a mensagem:Lembre-se disso se estiver usando o Groovy em seu aplicativo Spring Boot.
fonte
Para recuperar o mapa da configuração, você precisará da classe de configuração. A anotação @Value não resolverá o problema, infelizmente.
Application.yml
Classe de configuração:
fonte
Solução para puxar o mapa usando @Value da propriedade application.yml codificada como multilinha
Aqui, o valor da propriedade do mapa "my-map-property-name" é armazenado no formato JSON dentro de uma string e nós alcançamos várias linhas usando \ no final da linha
Mais explicação
\ no yaml é usado para quebrar a string em várias linhas
\ " é um caractere de escape para" (aspas) na string yaml
JSON {key: value} em yaml que será convertido em Map por @Value
# {} é a expressão SpEL e pode ser usado em @Value para converter json int Map ou Array / list Reference
Testado em um projeto de bota de mola
fonte
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding
fonte
Você pode torná-lo ainda mais simples, se quiser evitar estruturas extras.
Em seguida, use-o normalmente, por exemplo, com um construtor:
fonte