前言:Spring表达式语言(简称SpEL)是一种与JSP2的EL功能类似的表达式语言,它可以在运行时查询和操作对象图。与JSP2的EL相比,SpEL功能更加强大,它甚至支持方法调用和基本字符串模板函数。SpEL可以独立于Spring容器使用——只是当成简单的表达式语言来使用;也可以在Annotation或XML配置中使用SpEL,这样可以充分利用SpEL简化Spring的Bean配置。
注:在Struts笔记中提及的OGNL表达式也是一种与JSP2的EL功能类似的表达式语言,而OGNL并不是真正的编程语言,只是一种数据访问语言。详见:Struts2学习笔记(三)
官方教程(spring-framework-4.2.5.RELEASE-dist)可参考:III. Core Technologies -> 9. Spring Expression Language (SpEL)
一、使用Expression接口进行表达式求值
Spring的SpEL可以单独使用,可以使用SpEL对表达式计算、求值。SpEL主要提供了如下三个接口(位于org.springframework.expression包):
- ExpressionParser:该接口的实例负责解析一个SpEL表达式,返回一个Expression对象
- Expression:该接口的实例代表一个表达式
- EvaluationContext:代表计算表达式值的上下文,当SpEL表达式中含有变量时,程序将需要使用该API来计算表达式的值
Expression实例代表一个表达式,它包含了如下方法用于计算,得到表达式的值:
- Object getValue():计算表达式的值
- <T> T getValue(Class<T> desiredResultType):计算表达式的值,而且尝试将该表达式的值当成desiredResultType类型处理
- Object getValue(EvaluationContext context):使用指定的EvaluationContext来计算表达式的值(其中EvaluationContext相当于容器包含着Expression表达式中所需要用到的值,如果是根对象,那么连对象名称都可以省略直接使用)
- <T> T getValue(EvaluationContext context,Class<T> desiredResultType):使用指定的EvaluationContext来计算表达式的值,而且尝试将该表达式的值当成desiredResultType类型处理
- Object getValue(Object rootObject):以rootObject作为表达式的root对象来计算表达式的值
- <T> T getValue(Object rootObject,Class<T> desiredResultType):以rootObject作为表达式的root对象来计算表达式的值,而且尝试将该表达式的值当成desiredResultType类型处理
示例如下:
public class Person {
private Integer id;
private String name;
private Date birth;
// 无参数的构造器
public Person() {
}
// 初始化全部成员变量的构造器
public Person(Integer id, String name, Date birth) {
this.id = id;
this.name = name;
this.birth = birth;
}
// 省略所有的setter和getter方法
}
public class SpELTest {
public static void main(String[] args) {
// 创建一个ExpressionParser对象,用于解析表达式
ExpressionParser parser = new SpelExpressionParser();
// 最简单的字符串表达式
Expression exp = parser.parseExpression("'HelloWorld'");
System.out.println("'HelloWorld'的结果: " + exp.getValue());
// 调用方法的表达式
exp = parser.parseExpression("'HelloWorld'.concat('!')");
System.out.println("'HelloWorld'.concat('!')的结果: " + exp.getValue());
// 调用对象的getter方法
exp = parser.parseExpression("'HelloWorld'.bytes");
System.out.println("'HelloWorld'.bytes的结果: " + exp.getValue());
// 访问对象的属性(d相当于HelloWorld.getBytes().