【发布时间】:2010-01-11 11:45:25
【问题描述】:
Spring 3 引入了一个新的expression language (SpEL),可以在 bean 定义中使用。语法本身是相当明确的。
尚不清楚的是,SpEL 如何与先前版本中已经存在的属性占位符语法进行交互(如果有的话)。 SpEL 是否支持属性占位符,还是我必须结合两种机制的语法并希望它们结合起来?
让我举一个具体的例子。我想使用属性语法${x.y.z},但添加了elvis operator 提供的“默认值”语法来处理${x.y.z} 未定义的情况。
我尝试了以下语法但没有成功:
#{x.y.z?:'defaultValue'}#{${x.y.z}?:'defaultValue'}
第一个给我
找不到字段或属性“x” 在类型的对象上 'org.springframework.beans.factory.config.BeanExpressionContext'
这表明 SpEL 无法将其识别为属性占位符。
第二种语法抛出一个异常,表示无法识别占位符,因此正在调用占位符解析器,但由于未定义属性,因此按预期失败。
文档没有提到这种交互,所以要么这样的事情是不可能的,要么没有记录。
有人能做到吗?
好的,我为此想出了一个小型的、独立的测试用例。这一切都按原样工作:
首先,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"));
}
}
挑战 - 在 bean 文件中提出一个 SpEL 表达式,它允许我在 ${x.y.z} 无法解析的情况下指定默认值,并且此默认值 必须 指定为一部分的表达式,没有外化在另一个属性集中。
【问题讨论】:
-
你把表达式放在哪里?在代码中,或在您的 xml / @Value / 等中。
-
在 bean 定义 XML 中,例如
<property name="prop" ref="<exp>"/> -
不确定它是否合适,但是 - 你试过 value= 而不是 ref= 吗?
-
我没有尝试过,不,但它是我试图解决的 bean 引用,而不是一个值。
ref="${x.y.z}"适用于 Spring 2.5。