[SPRING] 스프링 3 표현식 언어는 부동산 자리 표시 자와 어떻게 상호 작용합니까?
SPRING스프링 3 표현식 언어는 부동산 자리 표시 자와 어떻게 상호 작용합니까?
Spring 3에서는 Bean 정의에서 사용할 수있는 새로운 표현 언어 (SpEL)를 도입했습니다. 구문 자체는 상당히 잘 정의되어 있습니다.
확실하지 않은 점은 SpEL이 이전 버전에 이미 있던 속성 자리 표시 자 구문과 상호 작용하는 방법입니다. SpEL은 부동산 플레이스 홀더를 지원합니까? 아니면 두 가지 메커니즘의 구문과 그들이 결합되기를 희망해야합니까?
구체적인 예를 들어 보겠습니다. $ {x.y.z} 속성 구문을 사용하고 싶지만 $ {x.y.z}가 정의되지 않은 경우를 처리하기 위해 elvis 연산자에서 제공하는 "기본값"구문을 추가해야합니다.
성공없이 다음 구문을 시도했다.
첫 번째 것은 나에게 준다.
이것은 SpEL이 이것을 부동산 자리 표시 자라고 인식하지 못한다고 제안합니다.
두 번째 구문은 자리 표시자를 인식하지 못한다는 예외를 throw하므로 자리 표시 자 확인자가 호출되지만 속성이 정의되어 있지 않으므로 예상대로 실패합니다.
문서는 이러한 상호 작용에 대한 언급이 없으므로 그러한 일이 불가능하거나 문서화되지 않았습니다.
누구든지이 일을 할 수 있었습니까?
좋아, 나는 이것을 위해 작고 독립적 인 테스트 케이스를 생각해 냈다. 이 모든 것이 그대로 작동합니다.
먼저 bean 정의 :
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
<context:property-placeholder properties-ref="myProps"/>
<util:properties id="myProps">
<prop key="x.y.z">Value A</prop>
</util:properties>
<bean id="testBean" class="test.Bean">
<!-- here is where the magic is required -->
<property name="value" value="${x.y.z}"/>
<!-- I want something like this
<property name="value" value="${a.b.c}?:'Value B'"/>
-->
</bean>
</beans>
그런 다음, 간단한 bean 클래스 :
패키지 테스트;
public class Bean {
String value;
public void setValue(String value) {
this.value = value;
}
}
마지막으로 테스트 케이스는 다음과 같습니다.
package test;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class PlaceholderTest {
private @Resource Bean testBean;
@Test
public void valueCheck() {
assertThat(testBean.value, is("Value A"));
}
}
문제는 $ {xyz}를 해결할 수없는 경우에 기본값을 지정할 수있는 beans 파일의 SpEL 표현식을 제시하는 것입니다.이 기본값은 다른 속성에 외부화되지 않은 표현식의 일부로 지정해야합니다 세트.
해결법
-
==============================
1.SpEL 표현식에서 속성 자리 표시 자에 액세스하려면 다음 구문을 사용할 수 있습니다. # { '$ {x.y.z}'}. Hovewer는 $ {x.y.z}를 해결할 수 없으면 예외를 throw하기 때문에 엘비스 연산자 및 기본값에 대한 문제를 해결할 수 없습니다.
SpEL 표현식에서 속성 자리 표시 자에 액세스하려면 다음 구문을 사용할 수 있습니다. # { '$ {x.y.z}'}. Hovewer는 $ {x.y.z}를 해결할 수 없으면 예외를 throw하기 때문에 엘비스 연산자 및 기본값에 대한 문제를 해결할 수 없습니다.
하지만 속성에 대한 기본값을 선언하는 데 SpEL이 필요하지 않습니다.
<context:property-placeholder location="..." properties-ref="defaultValues"/> <bean id = "defaultValues" class = "org.springframework.beans.factory.config.PropertiesFactoryBean"> <property name="properties"> <props> <prop key="x.y.z">ZZZ</prop> </props> </property> </bean> <bean ...> <property name = "..." value = "${x.y.z}" /> </bean>
-
==============================
2.콜론을 놓친 것 같습니다.
콜론을 놓친 것 같습니다.
#{ ${x.y.z} ?: 'defaultValue' }
-
==============================
3.자리 표시 자에 대한 기본값을 설정하려면 다음을 참조하십시오.
자리 표시 자에 대한 기본값을 설정하려면 다음을 참조하십시오.
<property name="value" value="${x.y.z:defaultValue}"/>
다음을 사용하여 SpEL과 자리 표시 자 사이의 상호 작용을 테스트하려는 경우
<!-- set value "77-AA-BB-CC-88" when property "x.y.z" not exist --> <property name="value" value="77-#{'AA-${x.y.z:BB}-CC'}-88"/>
-
==============================
4.$ {myProps.item : defaultValue}는 myProps.item이 없으면 defaultValue를 사용함을 의미합니다. 이것은 속성 자리 표시 자의 기본 동작입니다.
$ {myProps.item : defaultValue}는 myProps.item이 없으면 defaultValue를 사용함을 의미합니다. 이것은 속성 자리 표시 자의 기본 동작입니다.
# {defaultValue}는 리터럴 값에 대한 SpEL을 의미합니다.
따라서 $ {myProps.item : # {defaultValue}}는 myProps.item이 존재하지 않을 때 SpEL의 값을 계산하여 대상 필드에 할당하는 것을 의미합니다.
예:
$ {redis.auth : # {null}}은 redis.auth 속성이 존재하지 않을 때 null로 설정 함을 의미합니다.
-
==============================
5.사실 Property-Placeholder는 문제 자체를 해결할 수 있습니다. 나는. 속성 등록 정보를 사용하여 Spring 컨텍스트에서 명시 적으로 기본 설정을 지정할 수 있습니다. 그런 다음 사용해야 할 설정의 위치를 지정하고 localOverride 속성을 true로 설정할 수 있습니다. 이 경우 외부 자원 (location 속성에 지정된)에서 찾을 수있는 모든 속성은 기본 환경 (환경 내에서 명시 적으로 정의 됨)보다 우선합니다.
사실 Property-Placeholder는 문제 자체를 해결할 수 있습니다. 나는. 속성 등록 정보를 사용하여 Spring 컨텍스트에서 명시 적으로 기본 설정을 지정할 수 있습니다. 그런 다음 사용해야 할 설정의 위치를 지정하고 localOverride 속성을 true로 설정할 수 있습니다. 이 경우 외부 자원 (location 속성에 지정된)에서 찾을 수있는 모든 속성은 기본 환경 (환경 내에서 명시 적으로 정의 됨)보다 우선합니다.
희망을 도왔습니다.
-
==============================
6.자신의 예제에서 실행하려면이 코드를 추가해야합니다.
자신의 예제에서 실행하려면이 코드를 추가해야합니다.
<bean id="testBean" class="elvis.Bean"> <!-- here is where the magic is required <property name="value" value="${x.y.z}"/> --> <!-- I want something like this --> <property name="value" value="#{myProps.get('a.b.c')?:'Value B'}"/> </bean>
Spring은 a가 존재하지 않기 때문에 $ {a.b.c}를 멤버 a와 b의 멤버 c가 NPE가되는 결과로 평가하기 때문에 접근하지 못합니다.
-
==============================
7.당신은 할 수있다:
당신은 할 수있다:
<bean id="testBean" class="test.Bean"> <!-- if 'a.b.c' not found, then value="Value B" ---> <property name="value" value="${a.b.c:Value B}"/> </bean>
또는
... <!-- if 'a.b.c' not found , but 'a.b' found ,then value=${a.b} if 'a.b' also not found , then value="a" --> <property name="value" value="${a.b.c:${a.b:a}"/> ...
또는 ...
<!-- if 'a.b.c' not found , but 'a.b' found ,then value=${a.b} if 'a.b' also not found , then value="a" --> <property name="value" value="#{ '${a.b.c:}' ?: '${a.b:a}' }"/> ...
-
==============================
8.나는 다음을 시도하고 그것은 (꽤 못생긴) 일했다 :
나는 다음을 시도하고 그것은 (꽤 못생긴) 일했다 :
# {myProps.getProperty ( 'x.y.z')? : '값 B'}
-
==============================
9.Elvis을 사용할 필요가 없습니다. 콜론 뒤에 기본값을 제공하십시오.
Elvis을 사용할 필요가 없습니다. 콜론 뒤에 기본값을 제공하십시오.
@Value("${my.connection.timeout:5000}") private int myTimeoutMillis;
또는
@Retryable(maxAttemptsExpression = "#{${my.max.attempts:10}}") public void myRetryableMethod() { // ... }
from https://stackoverflow.com/questions/2041558/how-does-spring-3-expression-language-interact-with-property-placeholders by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring Data JPA를 Spring Container 외부에서 어떻게 사용합니까? (0) | 2018.12.29 |
---|---|
[SPRING] TestNG로 인한 스프링 의존성 삽입 (0) | 2018.12.29 |
[SPRING] Spring 부트가없는 Spring Cloud 구성 클라이언트 (0) | 2018.12.29 |
[SPRING] Tomcat & Spring Web - 클래스를 찾을 수 없음 예외 org.springframework.web.context.ContextLoaderListener (0) | 2018.12.29 |
[SPRING] Spring MVC / Spring Boot를 사용하여 적절한 전역 오류 처리기를 작성하는 방법 (0) | 2018.12.29 |