java 속성 파일의 HashMap을 Spring @Value로 채우는 방법
Spring @Value를 사용하여 속성 파일의 값을 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
이 키와 같이 매핑 가능한가요: value set
name1 = 100
name2 = 20
SPEL json과 같은 구문을 사용하여 속성 파일에 간단한 맵이나 목록의 맵을 작성할 수 있습니다.
simple.map={'KEY1': 'value1', 'KEY2': 'value3', 'KEY3': 'value5'}
map.of.list={\
'KEY1': {'value1','value2'}, \
'KEY2': {'value3','value4'}, \
'KEY3': {'value5'} \
}
사용했습니다.\
가독성을 높이기 위해 다중 줄 속성을 사용합니다.
그런 다음 자바에서는 다음과 같이 자동으로 액세스하고 파싱할 수 있습니다.@Value
이것처럼.
@Value("#{${simple.map}}")
Map<String, String> simpleMap;
@Value("#{${map.of.list}}")
Map<String, List<String>> mapOfList;
여기에${simple.map}
,@Value
속성 파일에서 다음 String을 가져옵니다.
"{'KEY1': 'value1', 'KEY2': 'value3', 'KEY3': 'value5'}"
그다음에 마치 안감이 들어간 것처럼 평가가 됩니다.
@Value("#{{'KEY1': 'value1', 'KEY2': 'value3', 'KEY3': 'value5'}}")
Spring @Value를 사용하여 속성 파일의 값을 HashMap에 매핑할 수 있습니까?
네.코드와 스펠의 도움을 조금 받았죠
먼저 스프링 빈에 대한 싱글을 생각해 보십시오. (스캔해야 합니다.)
@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
계급적 용법Splitter
구아바의 효용자세한 사항은 그 문서를 참고하시기 바랍니다.
그럼, 당신 콩에.
@Component
public class MyBean {
@Value("#{PropertySplitter.map('${service.expiration}')}")
Map<String, String> propertyAsMap;
}
그리고 마지막으로, 재산은:
service.expiration = name1:100,name2:20
그건 당신이 요청한 것과는 달라요 왜냐면 이건PropertySplitter
하나의 속성으로 작업을 수행합니다.Map
, 내 생각에 당신은 이런 방식으로 속성을 지정하거나 수정할 수 있을 것 같습니다.PropertySplitter
원하는 계층적 방식과 일치하도록 코드를 지정합니다.
Spring 4.1.x (구체적인 버전은 기억나지 않지만) 부터는 다음과 같은 작업을 할 수 있습니다.
@Value("#{${your.properties.key.name}}")
private Map<String, String> myMap;
당신의 속성을 입력합니다.당신의 속성 파일에 있는 key.name 은 다음과 같습니다.
your.properties.key.name={\
name1 : 100, \
name2 : 200 \
}
PropertySourcesPlaceholderConfigurebean을 만들어 앱에서 모두 작동하고 코드를 테스트할 단위 테스트 코드를 작성하는 경우 ${...} 자산 가치에 대한 자리 표시자가 예상대로 작동하지 않고 이상한 SpringEL 오류가 발생합니다.
내가 생각할 수 있는 가장 빠른 Spring Boot 기반 솔루션은 다음과 같습니다.특정 예에서는 한 시스템에서 다른 시스템으로 데이터를 마이그레이션하고 있습니다.그래서 우선순위라는 분야에 대한 매핑이 필요합니다.
먼저 다음과 같은 속성 파일(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
수업길에 올려놓기도 하고요
스프링 관리 콩/구성요소에서 지도를 사용하고자 할 경우 클래스에 다음과 같은 주석을 달아야 합니다.
@Component
@PropertySource("classpath:/priority-migration.properties")
지도에서 실제로 원하는 것은 물론 my.prefix 앞에 붙는 키/값 쌍, 즉 이 부분입니다.
{
0:0
10:1
15:2
20:2
}
구성요소에 주석을 달려면 다음을 사용해야 합니다.
@ConfigurationProperties("my.prefix")
수정 우선 순위에 대한 게터를 만듭니다.후자는 제 경우에 의무적인 것으로 증명되었습니다(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
}
}
이전 게시물에서 영감을 얻어 하나의 해결책을 만듭니다.
Spring 구성에 속성 파일을 등록합니다.
<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;
}
}
그리고 specifix 값으로 시작하는 모든 속성을 @Value 주석으로 해시맵에 매핑하려면 다음과 같이 하십시오.
@Service
public class MyServiceImpl implements MyService {
@Value("#{PropertyMapper.startWith('myProp', 'service.expiration.', true)}")
private HashMap<String, Object> portalExpirations;
다중선으로 부호화된 application.yml 속성 @Value from application.yml을 사용하여 맵을 끌어오기 위한 솔루션
application.yml
other-prop: just for demo
my-map-property-name: "{\
key1: \"ANY String Value here\", \
key2: \"any number of items\" , \
key3: \"Note the Last item does not have comma\" \
}"
other-prop2: just for demo 2
여기서 맵 속성 "my-map-property-name" 값은 문자열 내에 JSON 형식으로 저장되며 줄의 끝에 \를 사용하는 아카이브된 다중 행이 있습니다.
나의 자바 클래스 .java
import org.springframework.beans.factory.annotation.Value;
public class myJavaClass {
@Value("#{${my-map-property-name}}")
private Map<String,String> myMap;
public void someRandomMethod (){
if(myMap.containsKey("key1")) {
//todo...
} }
}
자세한 설명
\yamlit에서 줄을 여러 줄로 쪼개는 데 사용됩니다.
\"yaml 문자열의 "(quote)"에 대한 탈출 문자입니다.
@Value에 의해 맵으로 변환되는 yaml의 {key:value} JSON
#{ }이(가) SpEL 식이며 @Value에서 맵 또는 배열/목록 참조 json 변환에 사용할 수 있습니다.
스프링 부트 프로젝트에서 테스트됨
Yaml 이름과 동일한 변수 이름 사용
예:
private final HashMap<String, String> expiration
대신에
private final HashMap<String, String> expirations
또는 이와 유사한 in properties file이
org.code=0009,0008,0010
org.code.0009.channel=30,40
org.code.0008.channel=30,40
org.code.0010.channel=30,40
자바에서 org.code를 읽고 org.code를 읽고 각각의 org.code를 통과하여 build org.code..채널을 돌려 그것을 지도에 집어넣습니다.
언급URL : https://stackoverflow.com/questions/28369458/how-to-fill-hashmap-from-java-property-file-with-spring-value
'programing' 카테고리의 다른 글
Eclipse에서 Python Extension 디버깅 (0) | 2023.10.31 |
---|---|
CSS 네이티브 변수가 미디어 쿼리에서 작동하지 않음 (0) | 2023.10.31 |
ssh: 호스트 이름 github.com 을 확인할 수 없습니다. 이름이나 서비스를 알 수 없습니다. 치명적:리모트 엔드가 예기치 않게 끊어졌습니다. (0) | 2023.10.26 |
커널은 리눅스에서 실행 가능한 바이너리 파일을 어떻게 얻습니까? (0) | 2023.10.26 |
CSS 배경 이미지를 너비에 맞게 조정하고 높이를 비례하여 자동으로 조정해야 함 (0) | 2023.10.26 |