[SPRING] Spring Boot - application.yml에서 맵 삽입
SPRINGSpring Boot - application.yml에서 맵 삽입
기본적으로 여기에서 가져온 다음 application.yml이있는 Spring Boot 응용 프로그램이 있습니다.
info:
build:
artifact: ${project.artifactId}
name: ${project.name}
description: ${project.description}
version: ${project.version}
특정 값을 주입 할 수 있습니다.
@Value("${info.build.artifact}") String value
그러나 다음과 같이 전체지도를 삽입하고 싶습니다.
@Value("${info}") Map<String, Object> info
그것 (또는 비슷한 것)이 가능합니까? 분명히 yaml을 직접로드 할 수 있지만 Spring에서 이미 지원되는 것이 있는지 궁금해하고 있습니다.
해결법
-
==============================
1.@ConfigurationProperties를 사용하여지도를 삽입 할 수 있습니다.
@ConfigurationProperties를 사용하여지도를 삽입 할 수 있습니다.
import java.util.HashMap; import java.util.Map; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @EnableAutoConfiguration @EnableConfigurationProperties public class MapBindingSample { public static void main(String[] args) throws Exception { System.out.println(SpringApplication.run(MapBindingSample.class, args) .getBean(Test.class).getInfo()); } @Bean @ConfigurationProperties public Test test() { return new Test(); } public static class Test { private Map<String, Object> info = new HashMap<String, Object>(); public Map<String, Object> getInfo() { return this.info; } } }
질문에 yaml과 함께 이것을 실행하면 다음과 같은 결과가 나온다.
{build={artifact=${project.artifactId}, version=${project.version}, name=${project.name}, description=${project.description}}}
접두사를 설정하고 누락 된 속성을 처리하는 방법을 제어하는 등 다양한 옵션이 있습니다. 자세한 내용은 javadoc을 참조하십시오.
-
==============================
2.아래 해결책은 @Andy Wilkinson의 솔루션의 단축형입니다. 단, 별도의 클래스를 사용하거나 @Bean 주석이 달린 메서드를 사용할 필요가 없습니다.
아래 해결책은 @Andy Wilkinson의 솔루션의 단축형입니다. 단, 별도의 클래스를 사용하거나 @Bean 주석이 달린 메서드를 사용할 필요가 없습니다.
application.yml :
input: name: raja age: 12 somedata: abcd: 1 bcbd: 2 cdbd: 3
SomeComponent.java:
@Component @EnableConfigurationProperties @ConfigurationProperties(prefix = "input") class SomeComponent { @Value("${input.name}") private String name; @Value("${input.age}") private Integer age; private HashMap<String, Integer> somedata; public HashMap<String, Integer> getSomedata() { return somedata; } public void setSomedata(HashMap<String, Integer> somedata) { this.somedata = somedata; } }
우리는 @Value 주석과 @ConfigurationProperties 모두 문제없이 사용할 수 있습니다. 하지만 getter와 setter는 중요하며 @EnableConfigurationProperties는 @ConfigurationProperties를 작동시켜야합니다.
@Szymon Stepniak이 제공하는 그루비 솔루션에서이 아이디어를 시도했지만 누군가에게 유용 할 것이라고 생각했습니다.
-
==============================
3.오늘 같은 문제가 발생하지만 안타깝게도 Andy의 해결책이 효과가 없습니다. Spring Boot 1.2.1.RELEASE에서는 훨씬 쉽지만 몇 가지 사항을 알고 있어야합니다.
오늘 같은 문제가 발생하지만 안타깝게도 Andy의 해결책이 효과가 없습니다. Spring Boot 1.2.1.RELEASE에서는 훨씬 쉽지만 몇 가지 사항을 알고 있어야합니다.
내 application.yml에서 흥미로운 부분은 다음과 같습니다.
oauth: providers: google: api: org.scribe.builder.api.Google2Api key: api_key secret: api_secret callback: http://callback.your.host/oauth/google
제공자지도에는 하나의지도 항목 만 포함되어 있습니다. 제 목표는 다른 OAuth 제공자에게 동적 구성을 제공하는 것입니다. 이 yaml 파일에 제공된 구성을 기반으로 서비스를 초기화 할 서비스에이 맵을 삽입하려고합니다. 나의 초기 구현은 다음과 같다.
@Service @ConfigurationProperties(prefix = 'oauth') class OAuth2ProvidersService implements InitializingBean { private Map<String, Map<String, String>> providers = [:] @Override void afterPropertiesSet() throws Exception { initialize() } private void initialize() { //.... } }
응용 프로그램을 시작한 후 OAuth2ProvidersService의 공급자 맵이 초기화되지 않았습니다. Andy가 제안한 해결책을 시도했지만 제대로 작동하지 않았습니다. 그 응용 프로그램에서 Groovy를 사용하므로 private을 제거하고 Groovy가 getter와 setter를 생성하도록 결정했습니다. 그래서 내 코드는 다음과 같습니다.
@Service @ConfigurationProperties(prefix = 'oauth') class OAuth2ProvidersService implements InitializingBean { Map<String, Map<String, String>> providers = [:] @Override void afterPropertiesSet() throws Exception { initialize() } private void initialize() { //.... } }
그 작은 변화 후에 모든 것이 효과가있었습니다.
언급 할만한 가치가있는 것은 하나 있지만. 내가이 필드를 비공개로 만들고 setter 메서드에서 직접 인수 형식을 제공하기로 결정했습니다. 불행히도 그것은 작동하지 않을 것이다. 메시지와 함께 org.springframework.beans.NotWritablePropertyException이 발생합니다 :
Invalid property 'providers[google]' of bean class [com.zinvoice.user.service.OAuth2ProvidersService]: Cannot access indexed value in property referenced in indexed property path 'providers[google]'; nested exception is org.springframework.beans.NotReadablePropertyException: Invalid property 'providers[google]' of bean class [com.zinvoice.user.service.OAuth2ProvidersService]: Bean property 'providers[google]' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
스프링 부트 애플리케이션에서 Groovy를 사용하고 있다면 명심하십시오.
-
==============================
4.
foo.bars.one.counter=1 foo.bars.one.active=false foo.bars[two].id=IdOfBarWithKeyTwo public class Foo { private Map<String, Bar> bars = new HashMap<>(); public Map<String, Bar> getBars() { .... } }
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-Configuration-Binding
-
==============================
5.구성에서 맵을 검색하려면 구성 클래스가 필요합니다. @Value 주석은 유감스럽게도 트릭을 수행하지 않습니다.
구성에서 맵을 검색하려면 구성 클래스가 필요합니다. @Value 주석은 유감스럽게도 트릭을 수행하지 않습니다.
Application.yml
entries: map: key1: value1 key2: value2
구성 클래스 :
@Component @ConfigurationProperties("entries") @Getter @Setter public static class MyConfig { private Map<String, String> map; }
from https://stackoverflow.com/questions/24917194/spring-boot-inject-map-from-application-yml by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] OPTIONS Http 메소드에 대한 스프링 보안 비활성화 (0) | 2018.12.07 |
---|---|
[SPRING] 이 응용 프로그램에는 / error에 대한 명시적인 매핑이 없습니다. (0) | 2018.12.07 |
[SPRING] 다른 메소드 내부에서 메소드 호출을 위해 작동하지 않는 Spring AOP (0) | 2018.12.07 |
[SPRING] Spring에서 JSON deserializer를 작성하거나 확장하는 올바른 방법 (0) | 2018.12.07 |
[SPRING] 스프링 보안 로그인 페이지에서 추가 매개 변수를 전달하는 방법 (0) | 2018.12.07 |