本节介绍了 SpEL 接口的简单使用和它的表达语言。完整的语言参考可以在 语言参考中找到。
下面的代码引入了 SpEL API 来评估字面字符串表达式 Hello World。
这些类是在 org.springframework:spring-expression
jar 依赖包中
package cn.mrcode.study.springdocsread.data;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
/**
* @author mrcode
*/
public class DemoTest {
public static void main(String[] args) {
ExpressionParser parser = new SpelExpressionParser();
// 字面量表达式是 Hello World
Expression exp = parser.parseExpression("'Hello World'");
String message = (String) exp.getValue();
System.out.println(message);
}
}
你最可能使用的 SpEL 类和接口位于 org.springframework.expression
包及其子包中,如spel.support
。
ExpressionParser 接口负责解析一个表达式字符串。在前面的例子中,表达式字符串是一个由周围的单引号表示的字符串。Expression 接口负责评估先前定义的表达式字符串。在调用 parser.parseExpression
和 exp.getValue
时,可以分别抛出两个异常,即 ParsException 和 EvaluationException。
SpEL 支持广泛的功能,如调用方法、访问属性和调用构造函数。
在下面这个方法调用的例子中,我们对字符串调用 concat 方法:
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.concat('!')");
// 获取到的值就变成了 Hello World!
String message = (String) exp.getValue();
下面是调用 JavaBean 属性的例子,调用字符串属性 Bytes:
ExpressionParser parser = new SpelExpressionParser();
// 调用 'getBytes()' 方法
Expression exp = parser.parseExpression("'Hello World'.bytes");
byte[] bytes = (byte[]) exp.getValue();
这一行表达式将字符串转换为字节数组
SpEL 还支持通过使用标准的点符号(如 prop1.prop2.prop3 )来嵌套属性,也支持相应的属性值的设置。公共字段也可以被访问。
下面的例子显示了如何使用点符号来获得一个字面量的长度:
ExpressionParser parser = new SpelExpressionParser();
// 调用 getBytes().length
Expression exp = parser.parseExpression("'Hello World'.bytes.length");
// 值是 11
int length = (Integer) exp.getValue();
可以调用 String 的构造函数,而不是使用字符串字面量,如下例所示:
ExpressionParser parser = new SpelExpressionParser();
// 需要注意的是这里的方法调用,可以写 toUpperCase() 也可以不写后面的括号
Expression exp = parser.parseExpression("new String('hello world').toUpperCase");
String message = (String) exp.getValue();
注意通用方法的使用: public <T> T getValue(Class<T> desiredResultType)
。使用这个方法就不需要将表达式的值转换为期望的结果类型。如果值不能被 强转为 T 类型 或 不能通过 使用注册的类型转换器进行转换,就会抛出一个评估异常 EvaluationException。
SpEL 更常见的用法是提供一个表达式字符串,该字符串将针对特定的对象实例(称为根对象)进行评估。下面的例子显示了如何从 Inventor 类的一个实例中检索名称属性或创建一个布尔条件:
package cn.mrcode.study.springdocsread.data;
import java.util.Date;
/**
* @author mrcode
*/
public class Inventor {
private String name;
private String country;
private Date time;
public Inventor(String name, Date time, String country) {
this.name = name;
this.time = time;
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
}
package cn.mrcode.study.springdocsread.data;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import java.util.GregorianCalendar;
/**
* @author mrcode
*/
public class DemoTest {
public static void main(String[] args) {
// 创建和设置一个日历
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);
// 构造函数的参数是姓名、生日和国籍。
Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("name"); // 将名字解析为一个表达式
// 这里的 getValue 传入的是一个 根 对象
// 表示会将这个表达式,在根对象中来评估
String name = (String) exp.getValue(tesla);
// name == "Nikola Tesla"
exp = parser.parseExpression("name == 'Nikola Tesla'");
// 这里也是一样,从根对象中评估表达式,并根据传入的类型获得表达式的结果
boolean result = exp.getValue(tesla, Boolean.class);
// result == true
}
}