Spring EL 小記(一)

import java.lang.reflect.Method;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class StudySpEL {
    
    
    public static void main(String[] args) {
        getStart();
        parseContext();
        regFunction();
    }
    
    public static void getStart() 
    {
        //待解析的字符串,注意整個字符串是要解析的,若是要解析的字符串中包含
        //字符串要使用單引號,例如要寫成下面toParseString的樣子而不是
        //"welcome to el world + #name"這樣,由於不加引號,解析器
        //就會把它當作字段或者屬性來解析,而沒有這個屬性或者字段就會出錯
        final String toParseString = "'welcome to el world' + #name";
        
        //解析器,spring爲咱們提供了一個SpelExpressionParser解析器
        ExpressionParser parser = new SpelExpressionParser();
        
        //用解析器把待解析的字符串解析爲表達式Expression 
        //Expression的結構就是一些AST節點,例如:"'welcome to el world' + #name"字符串
        //就被拆分爲welcome to el wolrd #name這樣的節點,方便被EvaluationContext計算
        Expression expression = parser.parseExpression(toParseString);
        
        //EvaluationContext就是計算的上下文,用來替換Expression中的變量表達式的
        //例以下面就是把待解析字符串(上下文)中的name變量替換爲everybody
        EvaluationContext context = new StandardEvaluationContext();
        context.setVariable("name", "everybody");
        
        Object result = expression.getValue(context);
        System.out.println(result);
        
    }
    
    /**
     * 想spring中就會發現有 @Value("#{T(Math).PI * 4^2}") 這樣的註解
     * 它的待解析的字符串是#{}這樣的形式,怎麼辦,spring還有一個解析的上下文接口
     * ParserContext 它提供了一個默認的實現ParserContext.TEMPLATE_EXPRESSION
     * 就是解析以#{開頭以}結束的字符串,固然也能夠本身實現ParserContext接口
     */
    public static void parseContext()
    {
        //SpEL 支持+ - * / ^ % 等運算
        //SpEL 支持類型表達式 要求除了java.lang包之外的類使用類的全限定名稱
        //T(Math).PI 就是訪問java.lang.Math 的靜態字段PI
        final String toParseString = "#{T(Math).PI * 4^2}";
        ExpressionParser parser = new SpelExpressionParser();
        
        //由於待解析字符串是#{}這樣的形式因此使用ParserContext上下文,ParserContext.TEMPLATE_EXPRESSION
        Expression expression = parser.parseExpression(toParseString, ParserContext.TEMPLATE_EXPRESSION);
        Object value = expression.getValue(); //PI*16
        System.out.println(value);
    }
    
    /**
     * SpEL支持自定義函數,只能是靜態方法
     */
    public static void  regFunction()
    {
        final String toParseString = "#customerFunction(4,6)";
        ExpressionParser parser = new SpelExpressionParser();
        Expression expression = parser.parseExpression(toParseString);
        
        StandardEvaluationContext context = new StandardEvaluationContext();
        Method customerFuction = null;
        try {
             customerFuction = StudySpEL.class.getDeclaredMethod("customerFunction", int.class,int.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        //StandardEvaluationContext 纔有registerFunction方法,也能夠使用setVariable
        //註冊方法
        context.registerFunction("customerFunction", customerFuction);
        Integer value = expression.getValue(context, int.class);
        System.out.println(value);
        
    }
    
    public static int customerFunction(int a,int b)
    {
        return a+b;
    }
}

      雖然咱們平時可能不多用到很複雜的表達式,想解析mybatis的Mapper文件這種級別的,可是咱們能夠在註解上使用表達式,能夠讓註解有更多的動態特性,在結合aop,能夠把一些實現作的很優雅。因此瞭解一點spring的EL老是沒有壞處的。
java

相關文章
相關標籤/搜索