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 + 1900PlaceOfBirth.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被视为无(即不是零)。因此,任何其他值总是大于nullX > 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语法引用表达式中的变量

有效的变量名称必须由以下支持的一个或多个字符组成。

  • 字母:AZaz
  • 数字:09
  • 下划线: _
  • 美元符号: $
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表达式相关推荐

  1. 声明式事务、Spring 中常用注解、Ajax

    五. 声明式事务 编程式事务: 1.1 由程序员编程事务控制代码. 1.2 OpenSessionInView 编程式事务 声明式事务: 先引入依赖 <dependency><gro ...

  2. getHibernateTemplate()(Spring中常用的hql查询方法)

    Spring中常用的hql查询方法(getHibernateTemplate()) --------------------------------- 一.find(String queryStrin ...

  3. 利用计算机运算符编写检索式,计算机信息检索过程中常用的检索表达式

    信息检索过程中常用的检索表达式 检索表达式是检索策略的具体体现之一,简称检索式.检索式一般由检索词和各种逻辑运算符组成.具体来说,它是用检索系统规定的各种算符将检索词之间的逻辑关系.位置关系等连接起来 ...

  4. Spring Cache抽象-使用SpEL表达式

    概述 SpEl表达式 概述 在Spring Cache注解属性中(比如key,condition和unless),Spring的缓存抽象使用了SpEl表达式,从而提供了属性值的动态生成及足够的灵活性. ...

  5. Spring中常用注解及其作用

    1.@Component 它是这些注解里面最普通的一个注解,一般用于把普通pojo实例化到spring容器中. @Controller和@Service和@Repository是它的特殊情况,当一个类 ...

  6. 学习笔记【Spring中常用的设计模式】

    文章目录 简介 一. Spring用到的设计模式类别 1. 创建型模式 2. 结构性模式 3. 行为型模式 二. 设计模式详解 1. 工厂模式 1.1 简单工厂模式 1.2 工厂方法模式 1.3 抽象 ...

  7. Spring中常用注解的介绍

    spring中使用注解时配置文件的写法: <?xml version="1.0" encoding="UTF-8"?> <span style ...

  8. JSP隐含变量和Spring中Model在EL表达式中的读取顺序

    偶然中存在着必然,必然中存在着偶然 偶然出现的bug,必然存是由代码的不合理甚至错误的 代码逻辑越长,越复杂,就越容易出现bug 之前项目里几次偶然出现了一个bug,简单的描述就是第一次新增了之后进行 ...

  9. Spring中常用注解及作用

    1.@Component 类注解,设置该类为spring管理的bean,属性可以定义bean的id,添加在类定义的上方,@Component注解不可以添加在接口上,因为接口无法创建对象. eg: 步骤 ...

最新文章

  1. btc勒索病毒文件恢复及数据库恢复方案
  2. 原生Js_简易图片轮播模板
  3. 使用memcache的session入库
  4. 写一个排序算法,可以是冒泡排序或者是快速排序,假设待排序对象是一个维数组。(提示:不能使用系统已有函数,另外请仔细回忆以前学习过的 基础知识)...
  5. cacti linux cpu datasource,Cacti监控Cisco CPU 以及内存
  6. JDK源码系列(6)-StringBuilder
  7. JavaScript逻辑运算符“”和“||”短路原则的应用
  8. 如何判断自己是否到了该辞职的时候
  9. spring resttemplate中的转码
  10. android异步工作,Android异步消息机制详解
  11. 基于Spring Security Role过滤Jackson JSON输出内容
  12. 信用报告中的个人基本信息如何更新?
  13. 初中数学知识点总结_初中数学知识点
  14. 精神分裂症和失眠有没有关系
  15. group by 和where可以一起使用吗
  16. 省赛题目(4月23日)
  17. CSS实现图片自适应布局
  18. [置顶] android关机闹钟设计思路
  19. 在mac上通过Homebrew安装redis
  20. 计算机网络之应用层(文件传送协议、万维网)

热门文章

  1. 计算机科学湖北的大学排行,2015年湖北省大学最佳专业排行榜
  2. 《C Primer Plus》学习笔记—第9章
  3. C语言求最长公共子序列
  4. 关于移动端的touch事件(touchstart, touchmove, touchend,touchcancel)
  5. react native Xcode打包app发布ipa到蒲公英
  6. Python中的PIL给图片添加文字
  7. Vue 祖孙方法调用 祖父级方法在孙级调用 祖孙传参
  8. 软件开发人员必备利器
  9. office文件图标显示不正常
  10. hioki电阻测试仪3540软件,微电阻计/电阻测试仪/HIOKI 3540/HIOKI 3560/日置3540/日置3560...