Mam aplikację Spring Boot z następującymi application.yml
elementami - zaczerpniętymi w zasadzie stąd :
info:
build:
artifact: ${project.artifactId}
name: ${project.name}
description: ${project.description}
version: ${project.version}
Potrafię wstrzyknąć określone wartości, np
@Value("${info.build.artifact}") String value
Chciałbym jednak wstrzyknąć całą mapę czyli coś takiego:
@Value("${info}") Map<String, Object> info
Czy to (lub coś podobnego) jest możliwe? Oczywiście mogę bezpośrednio załadować yaml, ale zastanawiałem się, czy jest coś już obsługiwanego przez Spring.
java
spring
spring-boot
levant pied
źródło
źródło
info
mapy wMapBindingSample
środku (może dlatego, że jest używana do uruchamiania aplikacji w trakcieSpringApplication.run
rozmowy).info.build
zamiastinfo
z powyższej mapy?locations
(aby uzyskać właściwości z innegoyml
pliku zamiast domyślnychapplication.yml
) na@ConfigurationProperties
, zadziałało, z wyjątkiem tego, że nie spowodowało zastąpienia symboli zastępczych. Np. Gdybyś miałproject.version=123
ustawioną właściwość systemową , przykład podany w odpowiedzi zwróciłby sięversion=123
, a po ustawieniulocations
wróciłbyproject.version=${project.version}
. Czy wiesz, czy są tu jakieś ograniczenia?Poniższe rozwiązanie jest skrótem dla rozwiązania @Andy Wilkinson, z tym wyjątkiem, że nie musi ono używać oddzielnej klasy ani
@Bean
metody z adnotacjami.application.yml:
SomeComponent.java:
Możemy dołączyć zarówno
@Value
adnotacje, jak i@ConfigurationProperties
bez problemów. Ale metody pobierające i ustawiające są ważne i@EnableConfigurationProperties
muszą mieć@ConfigurationProperties
do działania.Wypróbowałem ten pomysł z fajnego rozwiązania dostarczonego przez @Szymon Stępniak, pomyślałem, że przyda się komuś.
źródło
@EnableConfigurationProperties
Dzisiaj mam ten sam problem, ale niestety rozwiązanie Andy'ego nie zadziałało. W Spring Boot 1.2.1.RELEASE jest jeszcze łatwiej, ale musisz być świadomy kilku rzeczy.
Oto interesująca część z mojego
application.yml
:providers
map zawiera tylko jeden wpis mapy, moim celem jest zapewnienie dynamicznej konfiguracji dla innych dostawców OAuth. Chcę wstrzyknąć tę mapę do usługi, która będzie inicjować usługi w oparciu o konfigurację podaną w tym pliku yaml. Moja pierwsza realizacja to:Po uruchomieniu aplikacji
providers
mapa wOAuth2ProvidersService
nie została zainicjowana. Wypróbowałem rozwiązanie zaproponowane przez Andy'ego, ale nie zadziałało. Używam Groovy w tej aplikacji, więc zdecydowałem się usunąćprivate
i pozwolić Groovy generować getter i setter. Więc mój kod wyglądał tak:Po tej drobnej zmianie wszystko działało.
Chociaż jest jedna rzecz, o której warto wspomnieć. Po tym, jak to działało, zdecydowałem się utworzyć to pole
private
i udostępnić setterowi prosty typ argumentu w metodzie ustawiającej. Niestety to nie zadziała. Powodujeorg.springframework.beans.NotWritablePropertyException
z komunikatem:Pamiętaj o tym, jeśli używasz Groovy w swojej aplikacji Spring Boot.
źródło
Aby pobrać mapę z konfiguracji, będziesz potrzebować klasy konfiguracyjnej. Adnotacja @Value niestety nie wystarczy.
Application.yml
Klasa konfiguracji:
źródło
Rozwiązanie do ściągania mapy przy użyciu @Value z właściwości application.yml zakodowanej jako wielowierszowa
Tutaj wartość naszej właściwości mapy „my-map-property-name” jest przechowywana w formacie JSON w ciągu znaków i uzyskaliśmy multilinię przy użyciu \ na końcu wiersza
Więcej wyjaśnień
\ w yaml służy do dzielenia łańcucha na multilinię
\ " jest znakiem ucieczki dla" (quote) w łańcuchu yaml
{klucz: wartość} JSON w yaml, który zostanie przekonwertowany na Map przez @Value
# {} jest to wyrażenie SpEL i może być użyte w @Value do konwersji json int Map lub Array / list Reference
Przetestowano w projekcie butów sprężynowych
źródło
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding
źródło
Możesz to jeszcze uprościć, jeśli chcesz uniknąć dodatkowych struktur.
A potem użyj go jak zwykle, na przykład z konstruktorem:
źródło