使用Spring Expression Language (SpEL)解析表达式

使用Spring Expression Language (SpEL)解析表达式

Spring Expression Language (SpEL) 是强大的表达式语言,支持查询、操作运行时对象图,以及解析逻辑、算术表达式。SpEL可以独立使用,无论你是否使用Spring框架。
本文尝试通过多个示例使用SpEL,探索其强大能力。

1. 环境准备

引入依赖:

compile group: 'org.springframework', name: 'spring-expression', version: '5.2.4.RELEASE'

读者可以选择最新版本或合适的版本。当然也可以下载相应jar文件。在调用下面的函数之前,按如下方式初始化一个类级属性SpelExpression解析器:

import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;

public class ElMain {
    private ExpressionParser parser;

    ElMain(){
        parser =  new SpelExpressionParser();
    }

    public static void main(String[] args) {
        ElMain elHelper = new ElMain();
        elHelper.evaluateLiteralExpresssions();
    }

    private static void print(Object message){
        System.out.println(message);
    }

2. SpEL示例应用

2.1. 解析直接文本

    private void evaluateLiteralExpresssions() {
        Expression exp = parser.parseExpression("'Hello World'");
        String message = (String) exp.getValue();
        print(message);

        exp = parser.parseExpression("6");
        Integer value = exp.getValue(Integer.class);
        print(value*2);
    }

这里直接解决字符串及数字文本。

2.2. 直接文本上调用方法

    /**
     * A function that tests method invocation on literals
     */
    private void methodInvocationOnLiterals() {
        Expression exp = parser.parseExpression("'Hello World'.concat('!')");
        String message = (String) exp.getValue();
        println(message);

        exp = parser.parseExpression("'Hello World'.length()");
        Integer size = exp.getValue(Integer.class);
        println(size);

        exp = parser.parseExpression("'Hello World'.split(' ')[0]");
        message = (String)exp.getValue();
        println(message);
    }

示例展示了在字符串上直接调用Java String类的public方法。

2.3. 访问对象属性和方法

    /**A function that tests accessing properties of objects**/
    private void accessingObjectProperties() {
        User user = new User("John", "Doe",  true, "[email protected]",30);
        Expression exp = parser.parseExpression("firstName");
        println((String)exp.getValue(user));

        exp = parser.parseExpression("isAdmin()==false");
        boolean isAdmin = exp.getValue(user, Boolean.class);
        println(isAdmin);

        exp = parser.parseExpression("email.split('@')[0]");
        String emailId = exp.getValue(user, String.class);
        println(emailId);

        exp = parser.parseExpression("age");
        Integer age = exp.getValue(user, Integer.class);
        println(age);
    }

表达式可以直接使用对象的属性与方法。我们看到方法与属性使用一样,只是多了调用括号。

2.4. 执行各种操作(比较、逻辑、算术)

SpEl支持下面几种操作:

关系比较操作:==, !=, <, <=, >, >=
逻辑操作: and, or, not
算术操作: +, -, /, *, %, ^

    private void operators() {
        User user = new User("John", "Doe", true,"[email protected]",  30);
        Expression exp = parser.parseExpression("age > 18");
        println(exp.getValue(user,Boolean.class));

        exp = parser.parseExpression("age < 18 and isAdmin()");
        println(exp.getValue(user,Boolean.class));
    }

2.5. 使用多个对象和变量

表达式不仅需要引用对象,而且可能需要引用多个不同类型的对象。我们可以把所有使用的对象都加入至上下文中。使用键值对的方式加入并引用。

    private void variables() {
        User user = new User("John", "Doe",  true, "[email protected]",30);
        Application app = new Application("Facebook", false);
        StandardEvaluationContext context = new StandardEvaluationContext();
        context.setVariable("user", user);
        context.setVariable("app", app);

        Expression exp = parser.parseExpression("#user.isAdmin() and #app.isActive()");
        Boolean result = exp.getValue(context,Boolean.class);
        println(result);
    }

2.6. 调用自定义函数

SpEl也可以调用自定义的函数,用户可以扩展业务逻辑。下面首先定义一个函数:、

public class StringHelper {
    public static boolean isValid(String url){
        return true;
    }
}

下面在SpEl中调用isValid方法:

    private void customFunctions() {
        try {
            StandardEvaluationContext context = new StandardEvaluationContext();
            context.registerFunction("isURLValid",
                    StringHelper.class.getDeclaredMethod("isValid", new Class[] { String.class }));

            String expression = "#isURLValid('http://google.com')";

            Boolean isValid = parser.parseExpression(expression).getValue(context, Boolean.class);
            println(isValid);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

3. 总结

本文通过示例介绍了SpEl中多种应用场景。读者可以利用这些功能实现更加灵活的功能应用。

你可能感兴趣的:(spring)