当前位置 : 首页 » 文章分类 :  开发  »  Spring-SpEL表达式

Spring-SpEL表达式

Spring Expression Language(SpEL) SpEL表达式

4 Spring Expression Language (SpEL)
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#expressions

Spring 从 3.x 开始支持 EL 表达式, Spring Expression Language(SpEL) 是类似于 OGNL 和 JSP EL 的表达式语言, 能够在运行时构建复杂表达式, 存取对象属性、调用对象方法等, 而且所有的 SpEL 都支持 XML 和 Annotation 两种方式, 使用的格式均为: #{SpEL expression}, 例如 @Value("#{'user'.toUpperCase()}")


SpEL表达式求值

4.1 Evaluation
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#expressions-evaluation

通用SpEL表达式求值流程

1、构造 SpelExpressionParser SpEL 解析器

2、调用解析器的 parseExpression() 方法解析表达式

3、调用表达式的 getValue() 方法获取结果,返回是 Object 类型需要强制类型转换,或者调用 getValue(@Nullable Class<T> desiredResultType) 返回指定类型

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

@Test
public void testSpEL() {
    // 1、构造解析器
    ExpressionParser parser = new SpelExpressionParser();

    // 2、解析表达式
    Expression expression = parser.parseExpression("'this is a str'");

    // 3、获取结果,返回是 Object 类型
    String strValue = (String) expression.getValue();
}

方法调用示例

ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.concat('!')");
String message = (String) exp.getValue();

访问JavaBean属性示例

ExpressionParser parser = new SpelExpressionParser();

// invokes 'getBytes()'
Expression exp = parser.parseExpression("'Hello World'.bytes");
byte[] bytes = (byte[]) exp.getValue();

SpEL 还支持嵌套属性,通过点表达式来访问,例如 prop1.prop2.prop3

ExpressionParser parser = new SpelExpressionParser();

// invokes 'getBytes().length'
Expression exp = parser.parseExpression("'Hello World'.bytes.length");
int length = (Integer) exp.getValue();

通过构造方法构造String

ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("new String('hello world').toUpperCase()");
String message = exp.getValue(String.class);

基于上下文根对象求值

// Create and set a calendar
GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);

// The constructor arguments are name, birthday, and nationality.
Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");

ExpressionParser parser = new SpelExpressionParser();

Expression exp = parser.parseExpression("name"); // Parse name as an expression
String name = (String) exp.getValue(tesla);
// name == "Nikola Tesla"

exp = parser.parseExpression("name == 'Nikola Tesla'");
boolean result = exp.getValue(tesla, Boolean.class);
// result == true

其中求值调用了 Object getValue(@Nullable Object rootObject) throws EvaluationException; 方法,表达式都是基于 rootObject 的。


EvaluationContext 求值上下文

变量可以通过 StandardEvaluationContext 的 setVariable() 方法设置到上下文中, 然后再 SpEL 表达式中通过 #变量名 使用变量;

// 定义变量
String name = "Tom";
EvaluationContext context = new StandardEvaluationContext();  // 表达式的上下文,
context.setVariable("myName", name);                        // 为了让表达式可以访问该对象, 先把对象放到上下文中
ExpressionParser parser = new SpelExpressionParser();
// 访问变量
parser.parseExpression("#myName").getValue(context, String.class);   // Tom , 使用变量

其中使用了 Object getValue(EvaluationContext context, @Nullable Object rootObject) throws EvaluationException; 求值方法,从上下文中读。


表达式

文本表达式

文本表达式(Literal Expressions) 支持字符串、数字(int, real, hex)、boolean 和 null.
字符串使用单引号分隔。单引号本身在字符串中使用两个单引号字符表示

ExpressionParser parser = new SpelExpressionParser();

// evals to "Hello World"
String helloWorld = (String) parser.parseExpression("'Hello World'").getValue();

double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue();

// evals to 2147483647
int maxValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue();

boolean trueValue = (Boolean) parser.parseExpression("true").getValue();

Object nullValue = parser.parseExpression("null").getValue();

逻辑运算(布尔运算)

逻辑与 and &&
逻辑或 or ||
逻辑非 not !


#this变量

变量 #this 表示当前操作的对象,常用于集合的过滤

// create an array of integers
List<Integer> primes = new ArrayList<Integer>();
primes.addAll(Arrays.asList(2,3,5,7,11,13,17));

SpEL判断集合是否包含Key


问题

Property or field ‘xx’ cannot be found on null

SpelEvaluationException: EL1007E: Property or field ‘xx’ cannot be found on null

引用前加上 @
@Document(collection = "#{@cname.collectionName}")

SpelEvaluationException: EL1007E: Property or field ‘cname’ cannot be found on null #15707
https://github.com/spring-projects/spring-boot/issues/15707


上一篇 达梦数据库

下一篇 Spring-Cloud-Gateway

阅读
评论
929
阅读预计4分钟
创建日期 2021-10-18
修改日期 2021-10-20
类别

页面信息

location:
protocol:
host:
hostname:
origin:
pathname:
href:
document:
referrer:
navigator:
platform:
userAgent:

评论