[SPRING] 스프링 @Value를 사용하여 자바 속성 파일에서 HashMap을 채우는 법
SPRING스프링 @Value를 사용하여 자바 속성 파일에서 HashMap을 채우는 법
Spring @Value를 사용하여 속성 파일에서 HashMap으로 값을 매핑 할 수 있습니까?
현재 나는 이와 같은 것을 가지고 있으며, 하나의 값을 매핑하는 것은 문제가되지 않습니다. 하지만 HashMap 만료에서 사용자 지정 값을 매핑해야합니다. 이게 가능한가?
@Service
@PropertySource(value = "classpath:my_service.properties")
public class SomeServiceImpl implements SomeService {
@Value("#{conf['service.cache']}")
private final boolean useCache = false;
@Value("#{conf['service.expiration.[<custom name>]']}")
private final HashMap<String, String> expirations = new HashMap<String, String>();
속성 파일 : 'my_service.properties'
service.cache=true
service.expiration.name1=100
service.expiration.name2=20
이 키처럼 맵핑 할 수 있습니까?
해결법
-
==============================
1.예, 그렇습니다. 코드와 Spel의 도움으로
예, 그렇습니다. 코드와 Spel의 도움으로
먼저,이 싱글 톤 Spring-bean을 살펴 보자. (당신은 그것을 스캔해야한다.)
@Component("PropertySplitter") public class PropertySplitter { /** * Example: one.example.property = KEY1:VALUE1,KEY2:VALUE2 */ public Map<String, String> map(String property) { return this.map(property, ","); } /** * Example: one.example.property = KEY1:VALUE1.1,VALUE1.2;KEY2:VALUE2.1,VALUE2.2 */ public Map<String, List<String>> mapOfList(String property) { Map<String, String> map = this.map(property, ";"); Map<String, List<String>> mapOfList = new HashMap<>(); for (Entry<String, String> entry : map.entrySet()) { mapOfList.put(entry.getKey(), this.list(entry.getValue())); } return mapOfList; } /** * Example: one.example.property = VALUE1,VALUE2,VALUE3,VALUE4 */ public List<String> list(String property) { return this.list(property, ","); } /** * Example: one.example.property = VALUE1.1,VALUE1.2;VALUE2.1,VALUE2.2 */ public List<List<String>> groupedList(String property) { List<String> unGroupedList = this.list(property, ";"); List<List<String>> groupedList = new ArrayList<>(); for (String group : unGroupedList) { groupedList.add(this.list(group)); } return groupedList; } private List<String> list(String property, String splitter) { return Splitter.on(splitter).omitEmptyStrings().trimResults().splitToList(property); } private Map<String, String> map(String property, String splitter) { return Splitter.on(splitter).omitEmptyStrings().trimResults().withKeyValueSeparator(":").split(property); } }
참고 : PropertySplitter 클래스는 Guava의 Splitter 유틸리티를 사용합니다. 자세한 내용은 해당 설명서를 참조하십시오.
그런 다음, 당신의 콩에서 :
@Component public class MyBean { @Value("#{PropertySplitter.map('${service.expiration}')}") Map<String, String> propertyAsMap; }
그리고 마지막으로, 재산 :
service.expiration = name1:100,name2:20
이 PropertySplitter는 Map으로 변형 된 하나의 속성으로 작동하기 때문에 사용자가 물어 본 것은 정확하지 않습니다.하지만이 속성을 지정하는 방법으로 전환하거나 PropertySplitter 코드를 수정하여보다 계층적인 네가 원하는대로.
-
==============================
2.나는 이전 게시물에서 영감을 얻은 하나의 솔루션을 만듭니다.
나는 이전 게시물에서 영감을 얻은 하나의 솔루션을 만듭니다.
스프링 설정에 등록 정보 파일 등록 :
<util:properties id="myProp" location="classpath:my.properties"/>
그리고 구성 요소를 만듭니다.
@Component("PropertyMapper") public class PropertyMapper { @Autowired ApplicationContext applicationContext; public HashMap<String, Object> startWith(String qualifier, String startWith) { return startWith(qualifier, startWith, false); } public HashMap<String, Object> startWith(String qualifier, String startWith, boolean removeStartWith) { HashMap<String, Object> result = new HashMap<String, Object>(); Object obj = applicationContext.getBean(qualifier); if (obj instanceof Properties) { Properties mobileProperties = (Properties)obj; if (mobileProperties != null) { for (Entry<Object, Object> e : mobileProperties.entrySet()) { Object oKey = e.getKey(); if (oKey instanceof String) { String key = (String)oKey; if (((String) oKey).startsWith(startWith)) { if (removeStartWith) key = key.substring(startWith.length()); result.put(key, e.getValue()); } } } } } return result; } }
그리고 특정 값으로 시작하는 모든 속성을 @Value 주석과 함께 HashMap에 매핑하고자 할 때 :
@Service public class MyServiceImpl implements MyService { @Value("#{PropertyMapper.startWith('myProp', 'service.expiration.', true)}") private HashMap<String, Object> portalExpirations;
-
==============================
3.제가 생각할 수있는 가장 빠른 스프링 부트 기반 솔루션은 다음과 같습니다. 필자의 특별한 예에서는 한 시스템에서 다른 시스템으로 데이터를 마이그레이션하고 있습니다. 그래서 우선 순위라는 필드에 대한 매핑이 필요합니다.
제가 생각할 수있는 가장 빠른 스프링 부트 기반 솔루션은 다음과 같습니다. 필자의 특별한 예에서는 한 시스템에서 다른 시스템으로 데이터를 마이그레이션하고 있습니다. 그래서 우선 순위라는 필드에 대한 매핑이 필요합니다.
먼저 다음과 같이 속성 파일 (priority-migration.properties)을 만들었습니다.
my.prefix.priority.0:0 my.prefix.priority.10:1 my.prefix.priority.15:2 my.prefix.priority.20:2 another.prefix.foo:bar
classpath에 놓으십시오.
스프링 관리 빈 / 컴포넌트에서 맵을 사용한다고 가정하면 다음과 같이 클래스에 주석을 추가하십시오.
@Component @PropertySource("classpath:/priority-migration.properties")
지도에서 실제로 원하는 것은 my.prefix라는 접두어가 붙은 키 / 값 쌍인 것입니다. 즉,이 부분은 다음과 같습니다.
{ 0:0 10:1 15:2 20:2 }
이를 달성하려면 구성 요소에 주석을 달아야합니다.
@ConfigurationProperties("my.prefix")
우선 순위 중위에 대한 getter를 생성합니다. 후자는 필자의 경우에 필수적인 것으로 판명되었다. (Sring Doc은 재산의 우선 순위를 갖고 그것을 변경 가능한 값으로 초기화하는 것만으로 충분하다고 말한다)
private final Map<Integer, Integer> priorityMap = new HashMap<>(); public Map<Integer, Integer> getPriority() { return priorityMap; }
끝에서
다음과 같이 보입니다.
@Component @ConfigurationProperties("my.prefix") @PropertySource("classpath:/priority-migration.properties") class PriorityProcessor { private final Map<Integer, Integer> priorityMap = new HashMap<>(); public Map<Integer, Integer> getPriority() { return priorityMap; } public void process() { Integer myPriority = priorityMap.get(10) // use it here } }
-
==============================
4.Spring 4.1.x (특정 버전을 기억하지 못함)에서 다음과 같이 할 수 있습니다.
Spring 4.1.x (특정 버전을 기억하지 못함)에서 다음과 같이 할 수 있습니다.
@Value("#{${your.properties.key.name}}") private Map<String, String> myMap;
속성 파일의 your.properties.key.name은 다음과 같아야합니다.
your.properties.key.name={\ name1 : 100, \ name2 : 200 \ }
앱에서 작동하도록 PropertySourcesPlaceholderConfigurer 빈을 만들어야하고 코드를 테스트 할 단위 테스트 코드를 작성하는 경우에는 $ {...} 속성 값의 자리 표시자가 예상대로 작동하지 않으며 이상한 SpringEL 오류가 나타날 것입니다.
-
==============================
5.SPEL json과 같은 구문을 사용하여 속성 파일에 간단한지도 또는 목록의지도를 작성할 수 있습니다.
SPEL json과 같은 구문을 사용하여 속성 파일에 간단한지도 또는 목록의지도를 작성할 수 있습니다.
simple.map={'KEY1': 'value1', 'KEY2': 'value3', 'KEY3': 'value5'} map.of.list={\ 'KEY1': {'value1','value2'}, \ 'KEY2': {'value3','value4'}, \ 'KEY3': {'value5'} \ }
가독성을 높이기 위해 \를 multiline 속성으로 사용했습니다.
그런 다음 자바에서는 @Value를 사용하여 자동으로 액세스하고 파싱 할 수 있습니다.
@Value("#{${simple.map}}") Map<String, String> simpleMap; @Value("#{${map.of.list}}") Map<String, List<String>> mapOfList;
$ {simple.map}을 사용하면 @Value가 속성 파일에서 다음 문자열을 가져옵니다.
"{'KEY1': 'value1', 'KEY2': 'value3', 'KEY3': 'value5'}"
그런 다음 인라인 된 것처럼 평가됩니다.
@Value("#{{'KEY1': 'value1', 'KEY2': 'value3', 'KEY3': 'value5'}}")
공식 문서에서 더 많은 것을 배울 수 있습니다.
from https://stackoverflow.com/questions/28369458/how-to-fill-hashmap-from-java-property-file-with-spring-value by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 봄 XML 파일 구성 계층 도움말 / 설명 (0) | 2018.12.06 |
---|---|
[SPRING] 스프링 XML 파일을 스프링 @Configuration 클래스로 변환 (0) | 2018.12.06 |
[SPRING] Spring 3 MVC 리소스 및 태그 <mvc : resources /> (0) | 2018.12.06 |
[SPRING] 봄 MVC - HttpMediaTypeNotAcceptableException (0) | 2018.12.05 |
[SPRING] Springboot / Angular2 - HTML5 URL 처리 방법 (0) | 2018.12.05 |