天天看點

使用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中多種應用場景。讀者可以利用這些功能實作更加靈活的功能應用。