本节介绍了 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 WorldExpression 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().lengthExpression exp = parser.parseExpression("'Hello World'.bytes.length");// 值是 11int 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}}
