rootObject

在表达式中直接写name和getName(),这时候Expression是无法解析的,因为其不知道name和getName()对应什么意思

@Test
public void test06() {
ExpressionParser parser = new SpelExpressionParser();
parser.parseExpression("name").getValue();
parser.parseExpression("getName()").getValue();
}

当表达式是基于某一个对象时,我们可以把对应的对象作为一个rootObject传递给对应的Experssion进行取值

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

设置上下文

通过指定EvaluationContext我们可以让name和getName()变得有意义,指定了EvaluationContext之后,Expression将根据对应的EvaluationContext来进行解析

@Test
public void test06() {
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"));
}

设置变量

@Test
public void test14() {
Object user = new Object() {
public String getName() {
return "abc";
}
};
EvaluationContext context = new StandardEvaluationContext();
//1、设置变量
context.setVariable("user", user);
ExpressionParser parser = new SpelExpressionParser();
//2、表达式中以#varName的形式使用变量
Expression expression = parser.parseExpression("#user.name");
//3、在获取表达式对应的值时传入包含对应变量定义的EvaluationContext
String userName = expression.getValue(context, String.class);
//表达式中使用变量,并在获取值时传递包含对应变量定义的EvaluationContext。
Assert.assertTrue(userName.equals("abc"));
}

#root

root在表达式中永远都指向对应EvaluationContext的rootObject对象

@Test
public void test14_1() {
Object user = new Object() {
public String getName() {
return "abc";
}
};
EvaluationContext context = new StandardEvaluationContext(user);
ExpressionParser parser = new SpelExpressionParser();
Assert.assertTrue(parser.parseExpression("#root.name").getValue(context).equals("abc"));
}

#this

this永远指向当前对象,其通常用于集合类型,表示集合中的一个元素

@Test
public void test14_2() {
ExpressionParser parser = new SpelExpressionParser();
List<Integer> intList = (List<Integer>)parser.parseExpression("{1,2,3,4,5,6}").getValue();
EvaluationContext context = new StandardEvaluationContext(intList);
//从List中选出为奇数的元素作为一个List进行返回,1、3、5。
List<Integer> oddList = (List<Integer>)parser.parseExpression("#root.?[#this%2==1]").getValue(context);
for (Integer odd : oddList) {
Assert.assertTrue(odd%2 == 1);
}
}

注册方法

StandardEvaluationContext允许我们在其中注册方法,然后在表达式中使用对应的方法,注册的方法必须是一个static类型的公有方法。注册方法是通过StandardEvaluationContext的registerFunction(funName,method)方法进行。参数1表示需要在表达式中使用的方法名称,参数2表示需要注册的java.lang.reflect.Method。在表达式中可以使用类似与#funName(params...)的形式来使用对应的方法

static class MathUtils {
public static int plusTen(int i) {
return i+10;
}
} @Test
public void test15() throws NoSuchMethodException, SecurityException {
ExpressionParser parser = new SpelExpressionParser();
//1、获取需要设置的java.lang.reflect.Method,需是static类型
Method plusTen = MathUtils.class.getDeclaredMethod("plusTen", int.class);
StandardEvaluationContext context = new StandardEvaluationContext();
//2、注册方法到StandardEvaluationContext,第一个参数对应表达式中需要使用的方法名
context.registerFunction("plusTen", plusTen);
//3、表达式中使用注册的方法
Expression expression = parser.parseExpression("#plusTen(10)");
//4、传递包含对应方法注册的StandardEvaluationContext给Expression以获取对应的值
int result = expression.getValue(context, int.class);
Assert.assertTrue(result == 20);
}

赋值

SPEL支持给表达式赋值,其是通过Expression的setValue()方法进行的,在赋值时需要指定rootObject或对应的EvaluationContext

@Test
public void test() {
ExpressionParser parser = new SpelExpressionParser();
Date d = new Date(); Expression expression = parser.parseExpression("date");
//设日期为1号 此处为date,其原理是通过调用Date类的setDate方法,必须指定是set开头的方法
expression.setValue(d, 1);
Object value = expression.getValue(d);
System.out.println(value); //其原理是通过调用Date类的setYear方法
expression = parser.parseExpression("year");
expression.setValue(d, 2023);
value = expression.getValue(d);
System.out.println(value);
}

对于List而言,在进行赋值时是通过元素的索引进行的,且对应的索引是必须存在的

@Test
public void test09() {
ExpressionParser parser = new SpelExpressionParser();
List<Integer> list = new ArrayList<Integer>(1);
list.add(0);//添加一个元素0
EvaluationContext context = new StandardEvaluationContext();
//添加变量以方便表达式访问
context.setVariable("list", list);
//设置第一个元素的值为1
Expression expression = parser.parseExpression("#list[0]");
expression.setValue(context, 1);
int first = (Integer) expression.getValue(context);
System.out.println(first);
}

对于Map的赋值是通过key进行的,对应的key在Map中可以先不存在

@Test
public void test10() {
ExpressionParser parser = new SpelExpressionParser();
Map<String, Integer> map = new HashMap<>();
EvaluationContext context = new StandardEvaluationContext();
//添加变量以方便表达式访问
context.setVariable("map", map);
//设置第一个元素的值为1
Expression expression = parser.parseExpression("#map['key1']");
expression.setValue(context, 1);
int first = (Integer) expression.getValue(context);
System.out.println(first);
}

Spring表达式语言(SPEL)学习(03)的更多相关文章

  1. Spring学习笔记--Spring表达式语言SpEL

    Spring3引入了Spring表达式语言(Spring Expression Language,SpEL).SpEL是一种强大的.简洁的装配Bean的方式,它通过运行期执行的表达式将值装配到Bean ...

  2. Spring表达式语言SpEL

    Spring表达式语言,简称SpEL,是一个支持运行时查询和操作对象图的强大的表达式语言.语法类似于EL:SpEL使用#{…}作为定界符,所有在大括号中的字符都将被认为是SpEL SpEL为bean属 ...

  3. Spring表达式语言SpEL简单介绍

    Spring3引入了Spring表达式语言(Spring Expression Language,SpEL). SpEL有非常多特性.比較经常使用的包含: 1.使用bean的id来引用bean, 以下 ...

  4. Spring3表达式语言(SpEL)学习笔记

    最新地址请访问:http://leeyee.github.io/blog/2011/06/19/spring-expression-language Spring Excpression Langua ...

  5. Spring表达式语言:SpEl

    概念: 是一个支持运行时查询和操作的对象图的强大的表达式语言. 语法类似于EL:SpEl使用#{ ...}作为定界符,所有在大括号中的 字符都将被认为是SpEl SpEl为bean的属性进行动态赋值提 ...

  6. Sping表达式语言--SpEL

    Spring表达式语言---SpEL 是一个支持运行时查询和操作对象的强大的表达式语言 语法类似于EL:SpEL使用#{...}作为定界符,所有在大括号中的字符都将被认为是SpEL SpEL为bean ...

  7. Spring ——表达式语言 Spring Expression Language (转载)

    目录 SpEL简介与功能特性 一.为什么需要Spring表达式语言 二.SpEL表达式Hello World! 三.SpEL表达式 3.1.文字表达式 3.2.SPEL语言特性 3.2.1.属性 3. ...

  8. Spring表达式语言 之 5.1 概述 5.2 SpEL基础(拾叁)

    5.1  概述 5.1.1  概述 Spring表达式语言全称为"Spring Expression Language",缩写为"SpEL",类似于Struts ...

  9. 开涛spring3(5.1&5.2) - Spring表达式语言 之 5.1 概述 5.2 SpEL基础

    5.1  概述 5.1.1  概述 Spring表达式语言全称为“Spring Expression Language”,缩写为“SpEL”,类似于Struts2x中使用的OGNL表达式语言,能在运行 ...

  10. 7 -- Spring的基本用法 -- 12... Spring 3.0 提供的表达式语言(SpEL)

    7.12 Spring 3.0 提供的表达式语言(SpEL) Spring表达式语言(简称SpEL)是一种与JSP 2 的EL功能类似的表达式语言,它可以在运行时查询和操作对象图.支持方法调用和基本字 ...

随机推荐

  1. 算法——AcWing算法提高课中代码和题解

    文章目录 第一章 动态规划 (完成情况:64/68) 数字三角形模型 最长上升子序列模型 背包模型 状态机模型 状态压缩DP 区间DP 树形DP 数位DP 单调队列优化DP 斜率优化DP 第二章 搜索 ...

  2. 33家国内外知名的手机广告平台的SDK名单汇总,吐血推荐

    下面格式:第一行是广告平台名称,第二行是SDK的包名特征,第三行是平台网站 多盟cn.domob.androidhttp://www.domob.cn/百度推广SDK com.baidu统计SDK c ...

  3. macbook-键盘连击问题002

    https://support.apple.com/zh-cn/HT205662 如何清洁 MacBook 或 MacBook Pro 的键盘 如果您的 MacBook(2015 年及更新机型)或 M ...

  4. Tarjan强连通分量详解

    1.简介: 在阅读下列内容之前,请务必了解 图论相关概念 中的基础部分. 强连通的定义是:有向图 G 强连通是指,G 中任意两个结点连通. 强连通分量(Strongly Connected Compo ...

  5. CF1526C2

    与简单版的思路完全一致,只需要改一下范围. 可以去看我简单版本的博客. 题目简化和分析: 给您一个数组,在其中选择若干个数使得: 任意前缀和 \(\ge 0\) 数量尽可能的大 我们可以使用贪心策略, ...

  6. 12. 用Rust手把手编写一个wmproxy(代理,内网穿透等), TLS的双向认证信息及token验证

    12. 用Rust手把手编写一个wmproxy(代理,内网穿透等), TLS的双向认证信息及token验证 项目 ++wmproxy++ gite: https://gitee.com/tickbh/ ...

  7. 16.2 ARP 主机探测技术

    ARP (Address Resolution Protocol,地址解析协议),是一种用于将 IP 地址转换为物理地址(MAC地址)的协议.它在 TCP/IP 协议栈中处于链路层,为了在局域网中能够 ...

  8. flyod

    最开始看错数据了没看到Q = 100 是50%的数据以为跑q遍floyd能过,结果只有30,其他全t 1.要注意题目中的条件,挖掘一些性质 var code = "92ce4972-7e0f ...

  9. Python合并多个Excel文件中的指定sheet

    本文将介绍一个用于合并多个Excel文件中指定sheet的Python代码.这个功能可以方便地整理和分析数据.我们将逐步解释代码的每个部分,并提供示例用法. 导入库 首先,我们导入了需要使用的三个库: ...

  10. P5404 [CTS2019] 重复 题解

    题目链接 观察题目,我们发现直接计算是困难的,先构造单个合法的 \(T\) 分析其性质. 为了构造出 \(T\),先考虑构造时 \(T\) 时什么时候会出现不合法的情况,此时 \(T\) 会有一段和 ...