0x00 简介

SpEL(Spring Expression Language)是Spring提供的一种表达式语言

能在运行时构建复杂表达式、存取对象图属性、对象方法调用等,并且能与Spring功能完美整合,如能用来配置Bean定义

表达式语言给静态Java语言增加了动态功能

0x01 表达式执行步骤

SpEL求表达式值时的步骤

1、构造一个解析器
    SpEL使用ExpressionParser接口表示解析器,提供SpelExpressionParser默认实现
2、解析器解析字符串表达式
    使用ExpressionParser的parseExpression来解析相应的表达式为Expression对象
3、构造上下文
    准备比如变量定义等等表达式需要的上下文数据
4、根据上下文得到表达式运算后的值
    通过Expression接口的getValue方法根据上下文获得表达式值
ExpressionParser parser = new SpelExpressionParser(); (1)
Expression exp = parser.parseExpression("'Hello World'"); (2)
String message = (String) exp.getValue(); (4)


ExpressionParser parser = new SpelExpressionParser();    (1)
Expression expression = parser.parseExpression("('Hello' + ' World').concat(#end)");   (2) 
EvaluationContext context = new StandardEvaluationContext();    (3)
context.setVariable("end", "!");    
Assert.assertEquals("Hello World!", expression.getValue(context));   (4) 

0x02 工作原理

0x03 主要接口

EvaluationContext

表示上下文环境
默认实现是org.springframework.expression.spel.support包中的StandardEvaluationContext类
使用setRootObject方法来设置根对象,使用setVariable方法来注册自定义变量,使用registerFunction来注册自定义函数等

下例表达式name表示对应EvaluationContext的rootObject的一个属性

public void EvaluationContextTest() {
    Object user = new Object() {
        public String getName() {
            return "abc";
        }
    };
    EvaluationContext context = new StandardEvaluationContext(user);
    ExpressionParser parser = new SpelExpressionParser();
    Assert.assertTrue(parser.parseExpression("name").getValue(context, String.class).equals("abc"));
    Assert.assertTrue(parser.parseExpression("getName()").getValue(context, String.class).equals("abc"));
}

ExpressionParser

表示解析器
默认实现是org.springframework.expression.spel.standard包中的SpelExpressionParser类,使用parseExpression方法将字符串表达式转换为Expression对象
对于ParserContext接口用于定义字符串表达式是不是模板,及模板开始与结束字符

public interface ExpressionParser {    
    Expression parseExpression(String expressionString);    
    Expression parseExpression(String expressionString, ParserContext context);    
}  


public void testParserContext() {    
    ExpressionParser parser = new SpelExpressionParser();    
    ParserContext parserContext = new ParserContext() {    
        @Override    
         public boolean isTemplate() {    
            return true;    
        }    
        @Override    
        public String getExpressionPrefix() {    
            return "#{";    
        }    
        @Override    
        public String getExpressionSuffix() {    
            return "}";    
        }    
    };    
    String template = "#{'Hello '}#{'World!'}";    
    Expression expression = parser.parseExpression(template, parserContext);    
    Assert.assertEquals("Hello World!", expression.getValue());    
}  

Expression

表示表达式对象
默认实现是org.springframework.expression.spel.standard包中的SpelExpression
提供getValue方法用于获取表达式值,提供setValue方法用于设置对象值

ExpressionParser parser = new SpelExpressionParser();    (1)
Expression expression = parser.parseExpression("('Hello' + ' World').concat(#end)");   (2) 
EvaluationContext context = new StandardEvaluationContext();    (3)
context.setVariable("end", "!");    
Assert.assertEquals("Hello World!", expression.getValue(context));   (4) 

0x04 主要功能

Literal expressions

Boolean and relational operators

Regular expressions

Class expressions

Accessing properties, arrays, lists, maps

Method invocation

Relational operators

Assignment

Calling constructors

Bean references

Array construction

Inline lists

Ternary operator

Variables

User defined functions

Collection projection

Collection selection

Templated expressions

参考:
https://docs.spring.io/spring/docs/3.0.x/reference/expressions.html
https://blog.csdn.net/zhoudaxia/article/details/38174169
https://github.com/elim168/elim168.github.io/blob/master/spring/bean/23.spel%E8%A1%A8%E8%BE%BE%E5%BC%8F.md