Spring中常用的SpEl表达式
Java 社区交流群
添加微信: 372787553 备注进群
SpEl 表达式语法
文字表达
支持的文字表达式类型是字符串、数值(整数、实数、十六进制)、布尔值和空值。字符串由单引号分隔。要将单引号本身放在字符串中,请使用两个单引号字符。
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();
Properties, Arrays, Lists, Maps, and Indexers
使用属性引用进行导航很容易。为此,请使用句点来指示嵌套的属性值
ExpressionParser parser = new SpelExpressionParser();
// evals to 1856
int year = (Integer) parser.parseExpression("birthdate.year + 1900").getValue(context);String city = (String) parser.parseExpression("placeOfBirth.city").getValue(context);
属性名称的第一个字母允许不区分大小写。因此,上面例子中的表达式可以分别写成Birthdate.Year + 1900
和 PlaceOfBirth.City
。此外,属性可以选择性地通过方法调用来访问——例如,getPlaceOfBirth().getCity()
而不是 placeOfBirth.city
.
数组和列表的内容使用方括号表示法获取,如下例所示:
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();// Inventions Array// evaluates to "Induction motor"
String invention = parser.parseExpression("inventions[3]").getValue(context, tesla, String.class);// Members List// evaluates to "Nikola Tesla"
String name = parser.parseExpression("members[0].name").getValue(context, ieee, String.class);// List and Array navigation
// evaluates to "Wireless communication"
String invention = parser.parseExpression("members[0].inventions[6]").getValue(context, ieee, String.class);
map的内容是通过在括号内指定文字键值来获得的。在下面的例子中,因为officers
映射的键是字符串,我们可以指定字符串文字:
// Officer's DictionaryInventor pupin = parser.parseExpression("officers['president']").getValue(societyContext, Inventor.class);// evaluates to "Idvor"
String city = parser.parseExpression("officers['president'].placeOfBirth.city").getValue(societyContext, String.class);// setting values
parser.parseExpression("officers['advisors'][0].placeOfBirth.country").setValue(societyContext, "Croatia");
Inline Lists
// evaluates to a Java list containing the four numbers
List numbers = (List) parser.parseExpression("{1,2,3,4}").getValue(context);List listOfLists = (List) parser.parseExpression("{{'a','b'},{'x','y'}}").getValue(context);
{}
本身意味着一个空列表。出于性能原因,如果列表本身完全由固定文字组成,则会创建一个常量列表来表示表达式(而不是在每次评估时构建一个新列表)。
Map
您还可以使用{key:value}
符号直接在表达式中表示映射
// evaluates to a Java map containing the two entries
Map inventorInfo = (Map) parser.parseExpression("{name:'Nikola',dob:'10-July-1856'}").getValue(context);Map mapOfMaps = (Map) parser.parseExpression("{name:{first:'Nikola',last:'Tesla'},dob:{day:10,month:'July',year:1856}}").getValue(context);
{:}
本身就意味着一个空Map。出于性能原因,如果映射本身由固定文字或其他嵌套常量结构(列表或映射)组成,则会创建一个常量映射来表示表达式(而不是在每次评估时构建一个新映射)。映射键的引用是可选的(除非键包含句点 ( .
))
数组构造
int[] numbers1 = (int[]) parser.parseExpression("new int[4]").getValue(context);// Array with initializer
int[] numbers2 = (int[]) parser.parseExpression("new int[]{1,2,3}").getValue(context);// Multi dimensional array
int[][] numbers3 = (int[][]) parser.parseExpression("new int[4][5]").getValue(context);
方法
您可以使用典型的 Java 编程语法来调用方法。您还可以对文字调用方法。还支持可变参数
// string literal, evaluates to "bc"
String bc = parser.parseExpression("'abc'.substring(1, 3)").getValue(String.class);// evaluates to true
boolean isMember = parser.parseExpression("isMember('Mihajlo Pupin')").getValue(societyContext, Boolean.class);
关系运算符
使用标准运算符表示法支持关系运算符(等于、不等于、小于、小于或等于、大于和大于或等于)
// evaluates to true
boolean trueValue = parser.parseExpression("2 == 2").getValue(Boolean.class);// evaluates to false
boolean falseValue = parser.parseExpression("2 < -5.0").getValue(Boolean.class);// evaluates to true
boolean trueValue = parser.parseExpression("'black' < 'block'").getValue(Boolean.class);
大于和小于的比较null
遵循一个简单的规则:null
被视为无(即不是零)。因此,任何其他值总是大于null
(X > null
总是true
)并且没有其他值永远小于没有(X < null
总是false
)
每个符号运算符也可以指定为纯字母等效项。这避免了使用的符号对嵌入表达式的文档类型(例如在 XML 文档中)具有特殊含义的问题。
lt
(<
)gt
(>
)le
(<=
)ge
(>=
)eq
(==
)ne
(!=
)div
(/
)mod
(%
)not
(!
)
逻辑运算符
SpEL 支持以下逻辑运算符:
and
(&&
)or
(||
)not
(!
)
以下示例显示了如何使用逻辑运算符:
// -- AND --// evaluates to false
boolean falseValue = parser.parseExpression("true and false").getValue(Boolean.class);// evaluates to true
String expression = "isMember('Nikola Tesla') and isMember('Mihajlo Pupin')";
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);// -- OR --// evaluates to true
boolean trueValue = parser.parseExpression("true or false").getValue(Boolean.class);// evaluates to true
String expression = "isMember('Nikola Tesla') or isMember('Albert Einstein')";
boolean trueValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);// -- NOT --// evaluates to false
boolean falseValue = parser.parseExpression("!true").getValue(Boolean.class);// -- AND and NOT --
String expression = "isMember('Nikola Tesla') and !isMember('Mihajlo Pupin')";
boolean falseValue = parser.parseExpression(expression).getValue(societyContext, Boolean.class);
数学运算符
您可以+
对数字和字符串使用加法运算符 ( )。您只能对数字使用减法 ( -
)、乘法 ( *
) 和除法 ( /
) 运算符。您还可以对数字使用模数 ( %
) 和指数幂 ( ^
) 运算符。强制执行标准运算符优先级
// Addition
int two = parser.parseExpression("1 + 1").getValue(Integer.class); // 2String testString = parser.parseExpression("'test' + ' ' + 'string'").getValue(String.class); // 'test string'// Subtraction
int four = parser.parseExpression("1 - -3").getValue(Integer.class); // 4double d = parser.parseExpression("1000.00 - 1e4").getValue(Double.class); // -9000// Multiplication
int six = parser.parseExpression("-2 * -3").getValue(Integer.class); // 6double twentyFour = parser.parseExpression("2.0 * 3e0 * 4").getValue(Double.class); // 24.0// Division
int minusTwo = parser.parseExpression("6 / -3").getValue(Integer.class); // -2double one = parser.parseExpression("8.0 / 4e0 / 2").getValue(Double.class); // 1.0// Modulus
int three = parser.parseExpression("7 % 4").getValue(Integer.class); // 3int one = parser.parseExpression("8 / 5 % 2").getValue(Integer.class); // 1// Operator precedence
int minusTwentyOne = parser.parseExpression("1+2-3*8").getValue(Integer.class); // -21
赋值运算符
要设置属性,请使用赋值运算符 ( =
)。这通常在对 的调用中完成,setValue
但也可以在对 的调用中完成getValue
。
Inventor inventor = new Inventor();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();parser.parseExpression("name").setValue(context, inventor, "Aleksandar Seovic");// alternatively
String aleks = parser.parseExpression("name = 'Aleksandar Seovic'").getValue(context, inventor, String.class);
变量
您可以使用#variableName
语法引用表达式中的变量
有效的变量名称必须由以下支持的一个或多个字符组成。
- 字母:
A
到Z
和a
到z
- 数字:
0
到9
- 下划线:
_
- 美元符号:
$
Inventor tesla = new Inventor("Nikola Tesla", "Serbian");EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
context.setVariable("newName", "Mike Tesla");parser.parseExpression("name = #newName").getValue(context, tesla);
System.out.println(tesla.getName()) // "Mike Tesla"
在#this
和#root
变量
该#this
变量总是被定义并且是指当前的评价对象(针对其不合格的引用解析)。该#root
变量始终被定义并引用根上下文对象。尽管#this
可能会随着表达式的组件的计算而变化,但#root
始终指的是根。
// create an array of integers
List<Integer> primes = new ArrayList<Integer>();
primes.addAll(Arrays.asList(2,3,5,7,11,13,17));// create parser and set variable 'primes' as the array of integers
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataAccess();
context.setVariable("primes", primes);// all prime numbers > 10 from the list (using selection ?{...})
// evaluates to [11, 13, 17]
List<Integer> primesGreaterThanTen = (List<Integer>) parser.parseExpression("#primes.?[#this>10]").getValue(context);
Bean 引用
如果已使用 bean 解析器配置了评估上下文,则可以使用@
符号从表达式中查找 bean
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new MyBeanResolver());// This will end up calling resolve(context,"something") on MyBeanResolver during evaluation
Object bean = parser.parseExpression("@something").getValue(context);
要访问工厂 bean 本身,您应该在 bean 名称前面加上一个&
符号
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setBeanResolver(new MyBeanResolver());// This will end up calling resolve(context,"&foo") on MyBeanResolver during evaluation
Object bean = parser.parseExpression("&foo").getValue(context);
三元运算符(If-Then-Else)
您可以使用三元运算符在表达式中执行 if-then-else 条件逻辑
String falseString = parser.parseExpression("false ? 'trueExp' : 'falseExp'").getValue(String.class);
在这种情况下,布尔值false
会返回字符串 value 'falseExp'
。一个更现实的例子如下:
parser.parseExpression("name").setValue(societyContext, "IEEE");
societyContext.setVariable("queryName", "Nikola Tesla");expression = "isMember(#queryName)? #queryName + ' is a member of the ' " +"+ Name + ' Society' : #queryName + ' is not a member of the ' + Name + ' Society'";String queryResultString = parser.parseExpression(expression).getValue(societyContext, String.class);
// queryResultString = "Nikola Tesla is a member of the IEEE Society"
表达式模板
表达式模板允许将文字文本与一个或多个评估块混合。每个评估块都用您可以定义的前缀和后缀字符分隔。一个常见的选择是#{ }
用作分隔符,如以下示例所示:
String randomPhrase = parser.parseExpression("random number is #{T(java.lang.Math).random()}",new TemplateParserContext()).getValue(String.class);// evaluates to "random number is 0.7038186818312008"
字符串的计算方法是将文字文本'random number is '
与#{ }
分隔符内的表达式的计算结果(在这种情况下,调用该random()
方法的结果)连接起来。该parseExpression()
方法的第二个参数的类型是ParserContext
。该ParserContext
接口用于影响表达式的解析方式,以支持表达式模板功能。定义TemplateParserContext
如下:
public class TemplateParserContext implements ParserContext {public String getExpressionPrefix() {return "#{";}public String getExpressionSuffix() {return "}";}public boolean isTemplate() {return true;}
}
Spring中常用的SpEl表达式相关推荐
- 声明式事务、Spring 中常用注解、Ajax
五. 声明式事务 编程式事务: 1.1 由程序员编程事务控制代码. 1.2 OpenSessionInView 编程式事务 声明式事务: 先引入依赖 <dependency><gro ...
- getHibernateTemplate()(Spring中常用的hql查询方法)
Spring中常用的hql查询方法(getHibernateTemplate()) --------------------------------- 一.find(String queryStrin ...
- 利用计算机运算符编写检索式,计算机信息检索过程中常用的检索表达式
信息检索过程中常用的检索表达式 检索表达式是检索策略的具体体现之一,简称检索式.检索式一般由检索词和各种逻辑运算符组成.具体来说,它是用检索系统规定的各种算符将检索词之间的逻辑关系.位置关系等连接起来 ...
- Spring Cache抽象-使用SpEL表达式
概述 SpEl表达式 概述 在Spring Cache注解属性中(比如key,condition和unless),Spring的缓存抽象使用了SpEl表达式,从而提供了属性值的动态生成及足够的灵活性. ...
- Spring中常用注解及其作用
1.@Component 它是这些注解里面最普通的一个注解,一般用于把普通pojo实例化到spring容器中. @Controller和@Service和@Repository是它的特殊情况,当一个类 ...
- 学习笔记【Spring中常用的设计模式】
文章目录 简介 一. Spring用到的设计模式类别 1. 创建型模式 2. 结构性模式 3. 行为型模式 二. 设计模式详解 1. 工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 1.3 抽象 ...
- Spring中常用注解的介绍
spring中使用注解时配置文件的写法: <?xml version="1.0" encoding="UTF-8"?> <span style ...
- JSP隐含变量和Spring中Model在EL表达式中的读取顺序
偶然中存在着必然,必然中存在着偶然 偶然出现的bug,必然存是由代码的不合理甚至错误的 代码逻辑越长,越复杂,就越容易出现bug 之前项目里几次偶然出现了一个bug,简单的描述就是第一次新增了之后进行 ...
- Spring中常用注解及作用
1.@Component 类注解,设置该类为spring管理的bean,属性可以定义bean的id,添加在类定义的上方,@Component注解不可以添加在接口上,因为接口无法创建对象. eg: 步骤 ...
最新文章
- btc勒索病毒文件恢复及数据库恢复方案
- 原生Js_简易图片轮播模板
- 使用memcache的session入库
- 写一个排序算法,可以是冒泡排序或者是快速排序,假设待排序对象是一个维数组。(提示:不能使用系统已有函数,另外请仔细回忆以前学习过的 基础知识)...
- cacti linux cpu datasource,Cacti监控Cisco CPU 以及内存
- JDK源码系列(6)-StringBuilder
- JavaScript逻辑运算符“”和“||”短路原则的应用
- 如何判断自己是否到了该辞职的时候
- spring resttemplate中的转码
- android异步工作,Android异步消息机制详解
- 基于Spring Security Role过滤Jackson JSON输出内容
- 信用报告中的个人基本信息如何更新?
- 初中数学知识点总结_初中数学知识点
- 精神分裂症和失眠有没有关系
- group by 和where可以一起使用吗
- 省赛题目(4月23日)
- CSS实现图片自适应布局
- [置顶] android关机闹钟设计思路
- 在mac上通过Homebrew安装redis
- 计算机网络之应用层(文件传送协议、万维网)
热门文章
- 计算机科学湖北的大学排行,2015年湖北省大学最佳专业排行榜
- 《C Primer Plus》学习笔记—第9章
- C语言求最长公共子序列
- 关于移动端的touch事件(touchstart, touchmove, touchend,touchcancel)
- react native Xcode打包app发布ipa到蒲公英
- Python中的PIL给图片添加文字
- Vue 祖孙方法调用 祖父级方法在孙级调用 祖孙传参
- 软件开发人员必备利器
- office文件图标显示不正常
- hioki电阻测试仪3540软件,微电阻计/电阻测试仪/HIOKI 3540/HIOKI 3560/日置3540/日置3560...