问题描述
Spring 3推出了一个新的(SpEL),可以在bean定义中使用。语法本身已经明确指定。
Spring 3 has introduced a new expression language (SpEL) which can be used in bean definitions. The syntax itself is fairly well specified.
不清楚的是,SpEL如何与先前版本中已存在的属性占位符语法进行交互。 SpEL是否支持属性占位符,或者我是否必须结合两种机制的语法并希望它们结合起来?
What isn't clear is how, if at all, SpEL interacts with the property placeholder syntax that was already present in prior versions. Does SpEL have support for property placeholders, or do I have to combine the syntax of both mechanisms and hope they combine?
让我举一个具体的例子。我想使用属性语法 $ {xyz}
,但添加了处理 $ {的情况xyz}
未定义。
Let me give a concrete example. I want to use the property syntax ${x.y.z}
, but with the addition of "default value" syntax as provided by the elvis operator to handle cases where ${x.y.z}
is undefined.
我尝试了以下语法但没有成功:
I've tried the following syntaxes without success:
-
#{xyz?:'defaultValue'}
-
#{ $ {xyz}?:'defaultValue'}
#{x.y.z?:'defaultValue'}
#{${x.y.z}?:'defaultValue'}
第一个给我
这表明SpEL不会将此识别为属性占位符。
which suggests that SpEL doesn't recognise this as a property placeholder.
第二种语法抛出一个异常,说明占位符未被识别,因此占位符为re解析器是被调用,但是因为没有定义属性而失败了。
The second syntax throws an exception saying that the placeholder is not recognised, so the placeholder resolver is being invoked, but is failing as expected, since the property is not defined.
文档没有提到这种交互,所以或者这样的事情是不可能的,或者它没有记录。
The docs make no mention of this interaction, so either such a thing is not possible, or it's undocumented.
任何人设法做到这一点?
Anyone managed to do this?
好的,我已经为此设计了一个小型,独立的测试用例。这一切都按原样运行:
OK, I've come up with a small, self-contained test case for this. This all works as-is:
首先,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类:
Then, the trivial bean class:
包测试;
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"));
}
}
挑战 - 想出一个SpEL表达式beans文件允许我在无法解析 $ {xyz}
的情况下指定默认值,并且此默认必须指定为部分表达式,而不是在另一个属性集中外部化。
The challenge - to come up with a SpEL expression in the beans file which allows me to specify a default value in cases where ${x.y.z}
cannot be resolved, and this default must be specified as part of the expression, not externalized in another property set.
推荐答案
要从SpEL表达式访问属性占位符,可以使用以下语法:#{'$ {xyz}'}
。 Hovewer,它无法用elvis运算符和默认值解决你的问题,因为当 $ {xyz}
无法解析时会抛出异常。
To access property placeholder from SpEL expression, the following syntax can be used: #{'${x.y.z}'}
. Hovewer, it can't solve your problem with elvis operator and default values, because it would throw an exception when ${x.y.z}
cannot be resolved.
但您不需要SpEL来声明属性的默认值:
But you don't need SpEL to declare default values for properties:
<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>
这篇关于Spring 3表达式语言如何与属性占位符交互?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!