Skip to main content
 首页 » 编程设计

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

2022年07月19日133lori

使用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, "john.doe@acme.com",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,"john.doe@acme.com",  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, "john.doe@acme.com",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中多种应用场景。读者可以利用这些功能实现更加灵活的功能应用。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/104533662