算术运算

@Test
public void test01() {
// 定义解析器
ExpressionParser parser = new SpelExpressionParser();
// 使用解析器解析表达式
// 获取解析结果
Assert.assertTrue(parser.parseExpression("(1+2)*5 + 8-6/2").getValue().equals(20));//加减乘除
Assert.assertTrue(parser.parseExpression("8%3").getValue().equals(2));//求余
Assert.assertTrue(parser.parseExpression("2.0e3").getValue().equals(2000.0));//指数
Assert.assertTrue(parser.parseExpression("2^3").getValue().equals(8));//指数
}

逻辑运算

@Test
public void test02() {
ExpressionParser parser = new SpelExpressionParser();
Assert.assertTrue(parser.parseExpression("true and true").getValue(Boolean.class));//与
Assert.assertTrue(parser.parseExpression("true or false").getValue(Boolean.class));//与
Assert.assertTrue(parser.parseExpression("!false").getValue(Boolean.class));//非
}

比较运算

@Test
public void test03() {
ExpressionParser parser = new SpelExpressionParser();
Assert.assertTrue(parser.parseExpression("5>3").getValue(Boolean.class));
Assert.assertTrue(parser.parseExpression("5<=8").getValue(Boolean.class));
Assert.assertTrue(parser.parseExpression("5==5").getValue(Boolean.class));
Assert.assertTrue(parser.parseExpression("5!=6").getValue(Boolean.class));
}

使用字符代替符号

@Test
public void test19() {
ExpressionParser parser = new SpelExpressionParser();
Assert.assertTrue(parser.parseExpression("1 lt 2").getValue(boolean.class));//1<2
Assert.assertTrue(parser.parseExpression("1 le 2").getValue(boolean.class));//1<=2
Assert.assertTrue(parser.parseExpression("2 gt 1").getValue(boolean.class));//2>1
Assert.assertTrue(parser.parseExpression("2 ge 1").getValue(boolean.class));//2>=1
Assert.assertTrue(parser.parseExpression("1 ne 2").getValue(boolean.class));//1!=2
Assert.assertTrue(parser.parseExpression("not false").getValue(boolean.class));//!false
}

正则表达式

@Test
public void test20 () {
ExpressionParser parser = new SpelExpressionParser();
Assert.assertTrue(parser.parseExpression("123 matches '\\d{3}'").getValue(Boolean.class));//正则匹配三位数字
}

instanceof类型判断

@Test
public void test21 () {
ExpressionParser parser = new SpelExpressionParser();
//检测字符串是否是String的实例。
Assert.assertTrue(parser.parseExpression("'123' instanceof T(String)").getValue(Boolean.class));
}

三目运算

@Test
public void test22 () {
ExpressionParser parser = new SpelExpressionParser();
Assert.assertTrue(parser.parseExpression("1>2 ? 1 : 2").getValue(int.class) == 2);//1跟2之间的较大者为2。
Assert.assertTrue(parser.parseExpression("1<2 ? 2 : 1").getValue(int.class) == 2);//1跟2之间的较大者为2。
}

字符串

操作字符串时需要通过单引号'来进行包裹,而当我们的字符串中包含单引号时,那么对应的单引号需要使用一个单引号进行转义,即连续两个单引号

@Test
public void test04() {
ExpressionParser parser = new SpelExpressionParser();
Assert.assertTrue(parser.parseExpression("'abc'").getValue().equals("abc"));
Assert.assertTrue(parser.parseExpression("'''abc'").getValue().equals("'abc"));
}

方法调用

字符串与对象

/**
* 方法调用
*/
@Test
public void test6(){
ExpressionParser parser = new SpelExpressionParser();
//直接访问String的length()方法。
Assert.assertTrue(parser.parseExpression("'abc'.length()").getValue().equals(3));
String bc = parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class);
System.out.println(bc);// bc // 传递参数,调用Society的isMember方法
Society societyContext = new Society();
boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(societyContext, Boolean.class);
System.out.println(isMember);// false
} public Boolean isNumber(Object object) {
return object instanceof Integer;
}

构造方法new

使用 new 运算符调用构造函数。对除原始类型(int、float 等)和 String 之外的所有类型使用完全限定的类名

/**
* new 调用构造方法
*/
@Test
public void test12(){
Inventor value = parser.parseExpression("new com.crab.spring.ioc.demo20.Inventor('ooo','xxx')").getValue(Inventor.class);
System.out.println(value.getName() + " " + value.getNationality()); // ooo xxx String value1 = parser.parseExpression("new String('xxxxoo')").getValue(String.class);
System.out.println(value1); // xxxxoo Expression exp = parser.parseExpression("new String('hello world').toUpperCase()");
String message = exp.getValue(String.class);
}

类类型T

类中的静态变量、静态方法属于Class, 可以通过T(xxx).xxx调用

@Test
public void test11(){
// 1 获取类的Class java.lang包下的类可以不指定全路径
Class value = parser.parseExpression("T(String)").getValue(Class.class);
System.out.println(value); // 2 获取类的Class 非java.lang包下的类必须指定全路径
Class dateValue = parser.parseExpression("T(java.util.Date)").getValue(Class.class);
System.out.println(dateValue); // 3 类中的静态变量 静态方法属于Class 通过T(xxx)调用
boolean trueValue = parser.parseExpression(
"T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR")
.getValue(Boolean.class); // true
System.out.println(trueValue);
Long longValue = parser.parseExpression("T(Long).parseLong('9999')").getValue(Long.class);
System.out.println(longValue);// 9999
}

表达式模板

表达式模板允许将文字文本与一个或多个评估块混合。每个评估块都由前缀和后缀字符分隔,默认是#{}。支持实现接口ParserContext自定义前后缀。调用parseExpression()时指定 ParserContext参数如:new TemplateParserContext(),#{}包起来的表达式会被计算

@Test
public void test23 () {
//the year is 2014
String expressionStr = "the year is #{T(java.util.Calendar).getInstance().get(T(java.util.Calendar).YEAR)}";
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression(expressionStr, new TemplateParserContext());
System.out.println(expression.getValue());
}

elvis设置默认值

SPEL表达式中支持a?:b这样的语法来设置默认值,表达如果a不为null时其结果为a,否则就为b

@Test
public void test () {
ExpressionParser parser = new SpelExpressionParser();
Assert.assertTrue(parser.parseExpression("#abc?:123").getValue().equals(123));//变量abc不存在
Assert.assertTrue(parser.parseExpression("1?:123").getValue().equals(1));//数字1不为null
}

?.嵌套属性安全访问

多级属性访问,如国家城市城镇nation.city.town三级访问,如果中间的 city是null则会抛出 NullPointerException 异常。为了避免这种情况的异常,SpEL借鉴了Groovy的语法?.,如果中间属性为null不会抛出异常而是返回null

/**
* 多级属性安全访问
*/
@Test
public void test18(){
Inventor inventor = new Inventor("xx", "oo");
inventor.setPlaceOfBirth(new PlaceOfBirth("北京", "中国")); // 正常访问
String city = parser.parseExpression("PlaceOfBirth?.city").getValue(context, inventor, String.class);
System.out.println(city); // 北京 // placeOfBirth为null
inventor.setPlaceOfBirth(null);
String city1 = parser.parseExpression("PlaceOfBirth?.city").getValue(context, inventor, String.class);
System.out.println(city1); // null // 非安全访问 异常
String city3 = parser.parseExpression("PlaceOfBirth.city").getValue(context, inventor, String.class);
System.out.println(city3); // 抛出异常
}

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

  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. Spring ——表达式语言 Spring Expression Language (转载)

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

  7. Sping表达式语言--SpEL

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

  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. Kubeflow基础知识

    kubeflow 基础知识 kubeflow 简介 kubeflow是谷歌开源的MLOps开源平台,其中包含的不同组件代表了机器学习生命周期的不同阶段. 下图是kubeflow组织ML工作流程: ku ...

  2. jmeter不用工具获取随机值的几种方法

    第一种:直接获取 "vcContent": "${__time(yyyyMMddHHmmss)}${__RandomString(8,QWERTYUIOPASDFGHJK ...

  3. 🎊OpenTiny Vue 3.11.0 发布:增加富文本、ColorPicker等4个新组件,迎来了贡献者大爆发!

    你好,我是 Kagol. 非常高兴跟大家宣布,2023年10月24日,OpenTiny Vue 发布了 v3.11.0 . OpenTiny 每次大版本发布,都会给大家带来一些实用的新特性,8.14 ...

  4. FreeSWITCH添加自定义endpoint之api及app开发

    操作系统 :CentOS 7.6_x64 FreeSWITCH版本 :1.10.9 之前写过FreeSWITCH添加自定义endpoint的文章,今天整理下api及app开发的笔记.历史文章可参考如下 ...

  5. OceanBase金融SQL、亿万级别据量优化案例(Row_number 开窗 + 分页SQL)

    最近优化了不少SQL,简单的SQL顺手搞了不好意思发出来了忽悠人,复杂很考验逻辑思维的,但是又不想分享出来(自己收藏的案例),怕被人抄袭思路. 今天遇到一条很有意思的SQL案例:  性能SQL(金融行 ...

  6. Transformers 中原生支持的量化方案概述

    本文旨在对 transformers 支持的各种量化方案及其优缺点作一个清晰的概述,以助于读者进行方案选择. 目前,量化模型有两个主要的用途: 在较小的设备上进行大模型推理 对量化模型进行适配器微调 ...

  7. 牛客多校第五场 K King of Range

    题意: 给定一个\(n\)个数得序列\(a_i\),给定\(m\)个询问,每次给出一个\(k\),寻找有多少个区间\([l, r]\)中最大值与最小值之差严格大于\(k\). 思路: 可以发现,如果已 ...

  8. java中Calendar日历类型常见方法

    Calendar是Java中常用的时间处理工具之一,它提供了很多日历类型常见方法,下面是一些常用的方法及对应的代码和运行结果. 1. 如何创建 Calendar 日历对象 Calendar 是一个抽象 ...

  9. Educational Codeforces Round 101 (Rated for Div. 2) E - A Bit Similar

    题目传送门 很巧妙的一道题.对于一个 \(n\)位的 \(01\)字符串,一共有 \(2^n\)种不同字符排列,对于任意一个固定排列,在 \(2^n\)种排列中只有一种排列与该固定排列处处不等,而题干 ...

  10. 本地数据备份与FTP远程数据迁移

    数据是电脑中最重要的东西.为了保证数据安全,我们经常会对数据进行备份.之前一直采用将重要数据拷贝至移动硬盘的方式实现备份,实现简单但每次都需要把所有文件拷贝一次,当文件很大时效率较低. 因此,考虑使用 ...