SpringEL表达式详细讲解及使⽤实例
⼀、简介
Spring3中引⼊了Spring表达式语⾔—SpringEL,SpEL是⼀种强⼤,简洁的装配Bean的⽅式,他可以通过运⾏期间执⾏的表达式将值装配到我们的属性或构造函数当中,更可以调⽤JDK中提供的静态常量,获取外部Properties⽂件中的的配置
⼆、⽤法
1、⽂本表达式
⽂本表达式⽀持: 字符串(需要⽤单引号声明)、⽇期、数字、布尔类型及null,对数字⽀持负数、指数及⼩数, 默认情况下实数使
⽤Double.parseDouble()进⾏表达式类型转换
parser.parseExpression("'hello'").getValue(String.class); // hello , 注意单引号
parser.parseExpression("1.024E+3").getValue(Long.class); // 1024 , 指数形式
parser.parseExpression("0xFFFF").getValue(Integer.class); // 65535 , ⼗六进制
parser.parseExpression("true").getValue(Boolean.class); // true
parser.parseExpression("null").getValue();
2、变量
// 定义变量
String name = "Tom";
EvaluationContext context = new StandardEvaluationContext(); // 表达式的上下⽂,
context.setVariable("myName", name); // 为了让表达式可以访问该对象, 先把对象放到上下⽂中
ExpressionParser parser = new SpelExpressionParser();
// 访问变量
parser.parseExpression("#myName").getValue(context, String.class); // Tom , 使⽤变量
// 直接使⽤构造⽅法创建对象
parser.parseExpression("new String('aaa')").getValue(String.class); // aaa
3、属性和⽅法调⽤
属性可直接使⽤属性名,属性名⾸字母⼤⼩写均可(只有⾸字母可不区分⼤⼩写);
数组、列表可直接通过下表形式(list[index])访问;
map可以直接把key当成索引来访问(map[key]);
⽅法可以直接访问;
// 准备⼯作
Person person = new Person("Tom", 18); // ⼀个普通的POJO
List<String> list = wArrayList("a", "b");
Map<String, String> map = wHashMap();
map.put("A", "1");
el表达式获取值map.put("B", "2");
EvaluationContext context = new StandardEvaluationContext(); // 表达式的上下⽂,
context.setVariable("person", person); // 为了让表达式可以访问该对象, 先把对象放到上下⽂中
context.setVariable("map", map);
context.setVariable("list", list);
ExpressionParser parser = new SpelExpressionParser();
// 属性
parser.parseExpression("#person.name").getValue(context, String.class); // Tom , 属性访问
parser.parseExpression("#person.Name").getValue(context, String.class); // Tom , 属性访问, 但是⾸字母⼤写了
// 列表
parser.parseExpression("#list[0]").getValue(context, String.class) // a , 下标
// map
parser.parseExpression("#map[A]").getValue(context, String.class); // 1 , key
// ⽅法
parser.parseExpression("#Age()").getValue(context, Integer.class); // 18 , ⽅法访问
4、类型
T操作符可以获取类型, 可以调⽤对象的静态⽅法
// 获取类型
parser.parseExpression("T(java.util.Date)").getValue(Class.class); // class java.util.Date
// 访问静态成员(⽅法或属性)
parser.parseExpression("T(Math).abs(-1)").getValue(Integer.class); // 1
// 判断类型
parser.parseExpression("'asdf' instanceof T(String)").getValue(Boolean.class); // true;
5、操作符
Spring EL ⽀持⼤多数的数学操作符、逻辑操作符、关系操作符.
关系操作符, 包括: eq(==), ne(!=), lt()<, le(<=), gt(>), ge(>=)
逻辑运算符, 包括: and(&&), or(||), not(!)
数学操作符, 包括: 加(+), 减(-), 乘(*), 除(/), 取模(%), 幂指数(^)
其他操作符, 如: 三元操作符, instanceof, 赋值(=), 正则匹配
另外三元操作符有个特殊的⽤法, ⼀般⽤于赋默认值, ⽐如: parseExpression("#name?:'defaultName'"), 如果变量name为空时设置默认值.
parser.parseExpression("1 > -1").getValue(Boolean.class); // true
parser.parseExpression("1 gt -1").getValue(Boolean.class); // true
parser.parseExpression("true or true").getValue(Boolean.class); // true
parser.parseExpression("true || true").getValue(Boolean.class); // true
parser.parseExpression("2 ^ 3").getValue(Integer.class); // 8
parser.parseExpression("true ? true : false").getValue(Boolean.class); // true
parser.parseExpression("#name ?: 'default'").getValue(context, String.class); // default
parser.parseExpression("1 instanceof T(Integer)").getValue(Boolean.class); // true
parser.parseExpression("'5.00' matches '^-?\d+(\.\d{2})?$'").getValue(Boolean.class); // true
parser.parseExpression("#person.name").getValue(context, String.class); // Tom , 原来的值
parser.parseExpression("#person.name = 'Jim'").getValue(context, String.class); // Jim , 赋值之后
parser.parseExpression("#person.name").getValue(context, String.class); // Jim, 赋值起了作⽤
6、避免空指针
当访问⼀个对象的属性或⽅法时, 若该对象为null, 就会出现空指针异常. 安全导航会判断对象是否为null,如果是的话, 就返回null⽽不是抛出空指针异常. 使⽤⽅式就是在对象后⾯加个?. 如下:
// 使⽤这种表达式可以避免抛出空指针异常
parser.parseExpression("#name?.toUpperCase()").getValue(context, String.class); // null
7、#this变量
有个特殊的变量#this来表⽰当前的对象. 常⽤于集合的过滤
// this 使⽤⽰例
parser.parseExpression("{1, 3, 5, 7}.?[#this > 3]").getValue(); // [5, 7]
8、集合选择
可以使⽤选择表达式对集合进⾏过滤或⼀些操作,从⽽⽣成⼀个新的符合选择条件的集合, 有如下⼀些形式:
[expression]: 选择符合条件的元素
^[expression]: 选择符合条件的第⼀个元素
$[expression]: 选择符合条件的最后⼀个元素
![expression]: 可对集合中的元素挨个进⾏处理
对于集合可以配合#this变量进⾏过滤, 对于map, 可分别对keySet及valueSet分别使⽤key和value关键字;
// 集合
parser.parseExpression("{1, 3, 5, 7}.?[#this > 3]").getValue(); // [5, 7] , 选择元素
parser.parseExpression("{1, 3, 5, 7}.^[#this > 3]").getValue(); // 5 , 第⼀个
parser.parseExpression("{1, 3, 5, 7}.$[#this > 3]").getValue(); // 7 , 最后⼀个
parser.parseExpression("{1, 3, 5, 7}.![#this + 1]").getValue(); // [2, 4, 6, 8] ,每个元素都加1
// map
Map<Integer, String> map = wHashMap();
map.put(1, "A");
map.put(2, "B");
map.put(3, "C");
map.put(4, "D");
EvaluationContext context = new StandardEvaluationContext();
context.setVariable("map", map);
parser.parseExpression("#map.?[key > 3]").getValue(context); // {4=D}
parser.parseExpression("#map.?[value == 'A']").getValue(context); // {1=A}
parser.parseExpression("#map.?[key > 2 and key < 4]").getValue(context); // {3=C}
9、模板表达式
模板表达式允许⽂字和表达式混合使⽤, ⼀般选择使⽤#{}作为⼀个定界符:
parser.parseExpression("他的名字为#{#person.name}", new TemplateParserContext()).getValue(context); // 他的名字为Tom
10、综合使⽤
//模板表达式,三元表达式结合使⽤
parser.parseExpression("#{#person.name!=null?'他的名字叫'+#person.name+'先⽣':'不知道名字'}", new TemplateParserContext()).getValue(context);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论