本节介绍了 SpEL 接口的简单使用和它的表达语言。完整的语言参考可以在 语言参考中找到

    下面的代码引入了 SpEL API 来评估字面字符串表达式 Hello World。

    这些类是在 org.springframework:spring-expression jar 依赖包中

    1. package cn.mrcode.study.springdocsread.data;
    2. import org.springframework.expression.Expression;
    3. import org.springframework.expression.ExpressionParser;
    4. import org.springframework.expression.spel.standard.SpelExpressionParser;
    5. /**
    6. * @author mrcode
    7. */
    8. public class DemoTest {
    9. public static void main(String[] args) {
    10. ExpressionParser parser = new SpelExpressionParser();
    11. // 字面量表达式是 Hello World
    12. Expression exp = parser.parseExpression("'Hello World'");
    13. String message = (String) exp.getValue();
    14. System.out.println(message);
    15. }
    16. }

    你最可能使用的 SpEL 类和接口位于 org.springframework.expression包及其子包中,如spel.support

    ExpressionParser 接口负责解析一个表达式字符串。在前面的例子中,表达式字符串是一个由周围的单引号表示的字符串。Expression 接口负责评估先前定义的表达式字符串。在调用 parser.parseExpressionexp.getValue时,可以分别抛出两个异常,即 ParsException 和 EvaluationException。

    SpEL 支持广泛的功能,如调用方法、访问属性和调用构造函数。

    在下面这个方法调用的例子中,我们对字符串调用 concat 方法:

    1. ExpressionParser parser = new SpelExpressionParser();
    2. Expression exp = parser.parseExpression("'Hello World'.concat('!')");
    3. // 获取到的值就变成了 Hello World!
    4. String message = (String) exp.getValue();

    下面是调用 JavaBean 属性的例子,调用字符串属性 Bytes:

    1. ExpressionParser parser = new SpelExpressionParser();
    2. // 调用 'getBytes()' 方法
    3. Expression exp = parser.parseExpression("'Hello World'.bytes");
    4. byte[] bytes = (byte[]) exp.getValue();

    这一行表达式将字符串转换为字节数组

    SpEL 还支持通过使用标准的点符号(如 prop1.prop2.prop3 )来嵌套属性,也支持相应的属性值的设置。公共字段也可以被访问。

    下面的例子显示了如何使用点符号来获得一个字面量的长度:

    1. ExpressionParser parser = new SpelExpressionParser();
    2. // 调用 getBytes().length
    3. Expression exp = parser.parseExpression("'Hello World'.bytes.length");
    4. // 值是 11
    5. int length = (Integer) exp.getValue();

    可以调用 String 的构造函数,而不是使用字符串字面量,如下例所示:

    1. ExpressionParser parser = new SpelExpressionParser();
    2. // 需要注意的是这里的方法调用,可以写 toUpperCase() 也可以不写后面的括号
    3. Expression exp = parser.parseExpression("new String('hello world').toUpperCase");
    4. String message = (String) exp.getValue();

    注意通用方法的使用: public <T> T getValue(Class<T> desiredResultType)。使用这个方法就不需要将表达式的值转换为期望的结果类型。如果值不能被 强转为 T 类型 或 不能通过 使用注册的类型转换器进行转换,就会抛出一个评估异常 EvaluationException。

    SpEL 更常见的用法是提供一个表达式字符串,该字符串将针对特定的对象实例(称为根对象)进行评估。下面的例子显示了如何从 Inventor 类的一个实例中检索名称属性或创建一个布尔条件:

    1. package cn.mrcode.study.springdocsread.data;
    2. import java.util.Date;
    3. /**
    4. * @author mrcode
    5. */
    6. public class Inventor {
    7. private String name;
    8. private String country;
    9. private Date time;
    10. public Inventor(String name, Date time, String country) {
    11. this.name = name;
    12. this.time = time;
    13. this.country = country;
    14. }
    15. public String getName() {
    16. return name;
    17. }
    18. public void setName(String name) {
    19. this.name = name;
    20. }
    21. public String getCountry() {
    22. return country;
    23. }
    24. public void setCountry(String country) {
    25. this.country = country;
    26. }
    27. public Date getTime() {
    28. return time;
    29. }
    30. public void setTime(Date time) {
    31. this.time = time;
    32. }
    33. }
    1. package cn.mrcode.study.springdocsread.data;
    2. import org.springframework.expression.Expression;
    3. import org.springframework.expression.ExpressionParser;
    4. import org.springframework.expression.spel.standard.SpelExpressionParser;
    5. import java.util.GregorianCalendar;
    6. /**
    7. * @author mrcode
    8. */
    9. public class DemoTest {
    10. public static void main(String[] args) {
    11. // 创建和设置一个日历
    12. GregorianCalendar c = new GregorianCalendar();
    13. c.set(1856, 7, 9);
    14. // 构造函数的参数是姓名、生日和国籍。
    15. Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");
    16. ExpressionParser parser = new SpelExpressionParser();
    17. Expression exp = parser.parseExpression("name"); // 将名字解析为一个表达式
    18. // 这里的 getValue 传入的是一个 根 对象
    19. // 表示会将这个表达式,在根对象中来评估
    20. String name = (String) exp.getValue(tesla);
    21. // name == "Nikola Tesla"
    22. exp = parser.parseExpression("name == 'Nikola Tesla'");
    23. // 这里也是一样,从根对象中评估表达式,并根据传入的类型获得表达式的结果
    24. boolean result = exp.getValue(tesla, Boolean.class);
    25. // result == true
    26. }
    27. }