一. SpringEL入门
Spring动态语言(简称SpEL) 是一个支持运行时查询和操作对象图的强大的动态语言,语法类似于EL表达式,具有诸如显示方法和基本字符串模板函数等特性.
1. 准备工作
需要导入jar包
spring-expression.jar
maven项目pom文件添加:
1 <dependency> 2 <groupId>org.springframework</groupId> 3 <artifactId>spring-expression</artifactId> 4 <version>4.3.10.RELEASE</version> 5 </dependency>
测试:
1 /** 2 * 在SpEL中,使用表达式非常简单,只需创建一个SpelExpressionParser实例即可,也就是首先创建一个SpEL *表达式解析器,然后调用ExpressionParser#parseExpression()方法对表达式进行解析,其中单引号表示 3 *String类型. 4 */ 5 public class SpelHello { 6 public static void main(String [] args){ 7 //TODO 测试SPRINGEL表达式 8 ExpressionParser parser = new SpelExpressionParser(); 9 Expression exp = parser.parseExpression("'hello'+'world'"); 10 String value = (String) exp.getValue(); 11 System.out.println(value); //helloworld 12 } 13 }
注意: SpEL被设计成一个可独立运行的模块,可以脱离Spring容器直接运行,因此只需引入SpEL的模块spring-expression即可,无须引入Spring的其他框架,接下来,在代码中就可以使用SpEL提供表达式解析类.
二.SpringEL核心接口
SpringEL的核心接口和核心类全部位于 org.springframework.expression包及其子包,以及spel.support中.
1. 核心接口介绍
ExpressionParser: 解析表达式字符串,表达式字符串是一个用单引号标注或者用转义的双引号标注的字符串.
Expression: 接口用来计算表达式字符串值
SpringEL支持一系列功能特性,比如方法调用,属性调用及构造器调用.
例如:
1 @Test 2 public void test1(){ 3 //TODO 测试SPRINGEL表达式解析函数 4 ExpressionParser parser = new SpelExpressionParser(); 5 Expression exp = parser.parseExpression("'hello'+'world'.concat('!!!')"); 6 String value = (String) exp.getValue(); 7 System.out.println(value); //输出结果helloworld!!! 8 }
2. EvaluationContext接口
示例:
1 @Test 2 public void test2(){ 3 //TODO 测试 EvaluationContext 4 User user = new User(); 5 user.setUserName("张三"); 6 user.setCredits(100); 7 ExpressionParser parser = new SpelExpressionParser(); 8 9 /** 10 * 创建一个 StandardEvaluationContext实例,指定一个跟对象作为求值目标对象,这样在求值表达式中就可以引用根 11 * 对象属性.在求值内部可以使用反射机制从注册对象中获取相应的属性. 12 */ 13 EvaluationContext context = new StandardEvaluationContext(user); 14 15 String userName = (String) parser.parseExpression("userName").getValue(context); 16 17 System.out.println(userName); 18 }
示例:
1 public class Simple { 2 public List<Boolean> booleansList = new ArrayList<Boolean>(); 3 4 }
测试:
1 @Test 2 public void test3(){ 3 //TODO 测试 EvaluationContext 4 //1 5 Simple simple = new Simple(); 6 simple.booleansList.add(true); //给Simple对象 属性的集合中添加一个值 7 //2 8 StandardEvaluationContext simpleContext = new StandardEvaluationContext(simple); 9 ExpressionParser parser = new SpelExpressionParser(); 10 //3 11 Expression expression = parser.parseExpression("booleansList[0]"); 12 //4 13 expression.setValue(simpleContext,"false"); 14 //5 15 Boolean bl = simple.booleansList.get(0); 16 System.out.println("bl---->"+bl); //输出结果: b1 - false 17 }
-
-
创建StandardEvaluationContext的内部使用反射机制创建Simple操作对象.
-
创建SpEL表达式
-
给SpEL表达式设置操作上下文对象. 以及设置对应的值
-
获取修改后的结果!
三. SpEL基础表达式
文本表达式支持字符串,日期,数字(正数,实数及十六进制数),布尔类型及null,其中字符串需使用单引号或者反斜杠+双引号包含起来,如" 'String类型' " , " "String类型" ",单引号字符可使用 " ' " 表示.
test:
1 @Test 2 public void test4(){ 3 //TODO SpEL基本类型解析 4 ExpressionParser parser = new SpelExpressionParser(); 5 //1.解析字符串 6 String hellworld =(String) parser.parseExpression("\"hello world\"").getValue(); 7 //2.解析双精度浮点 8 double doubleNumber = (Double) parser.parseExpression("3.1415926").getValue(); 9 //3.解析整数 10 int maxValue = (Integer) parser.parseExpression("0xFFFFFF").getValue(); 11 //4.解析boolean类型 12 boolean value = (Boolean) parser.parseExpression("true").getValue(); 13 //5.解析空值 14 Object nullValue = parser.parseExpression("null").getValue(); System.out.println(hellworld+doubleNumber+maxValue+value+nullValue); 15 16 }
2. 对象属性解析
在SpringEL中,可使用类似 "xxx.yyy.zzz" 的对象属性路径轻松的访问对象属性值.
1 public class Place { 2 private String city; 3 public Place(String city) { 4 this.city = city; 5 } 6 public String getCity() { 7 return city; 8 } 9 public void setCity(String city) { 10 this.city = city; 11 } 12 }
创建User类:
1 public class User { 2 private String userName; 3 private Integer credits; 4 private Place place; 5 public Place getPlace() { 6 return place; 7 } 8 public void setPlace(Place place) { 9 this.place = place; 10 } 11 public String getUserName() { 12 return userName; 13 } 14 public void setUserName(String userName) { 15 this.userName = userName; 16 } 17 public Integer getCredits() { 18 return credits; 19 } 20 public void setCredits(Integer credits) { 21 this.credits = credits; 22 } 23 }
测试:
1 @Test 2 public void test5(){ 3 //TODO 获取对象属性值 4 User user = new User(); 5 user.setCredits(100); 6 user.setUserName("王老五"); 7 user.setPlace(new Place("葫芦岛")); 8 //构建SpEL解析上下文 9 ExpressionParser parser = new SpelExpressionParser(); 10 EvaluationContext context = new StandardEvaluationContext(user); 11 //基本属性值获取 12 String username = (String)parser.parseExpression("userName").getValue(context); 13 System.out.println("username = " + username); 14 //支持运算 15 int credits = (Integer)parser.parseExpression("credits+10").getValue(context); 16 System.out.println("credits = " + credits); 17 //获取嵌套对象属性值 18 String city = (String)parser.parseExpression("place.city").getValue(context); 19 System.out.println("city = " + city); 20 21 }
3. 数组,集合类型解析
在SpEL中,支持数组,集合类型解析.数组支持标准Java语言创建方法,如"new int []{1,2,3}".List支持大括号括起来的内容,数据项之间用逗号隔开,如 "{1,2,3,4,5}", "{{'a','b'},{'c','d'}}".目前SpEL还不支持多维数组初始化,如 "new int[2][3]
1 @Test 2 public void test6(){ 3 //TODO 测试数组集合解析 4 ExpressionParser parser = new SpelExpressionParser(); 5 EvaluationContext context = new StandardEvaluationContext(user); 6 //数组获取 7 int [] array1 = (int[]) parser.parseExpression("new int[]{1,2,3}").getValue(); 8 System.out.println(Arrays.toString(array1)); 9 //集合获取 10 List list = (List) parser.parseExpression("{1,2,3,4}").getValue(); 11 12 List tList = (List) parser.parseExpression("{{123,456},{789,111}}").getValue(); 13 14 System.out.println(list+"\n"+tList); 15 //Map数据操作 16 Map map= (Map) parser.parseExpression("{username:'tom',age:11}").getValue(); 17 List mList = (List) parser.parseExpression("{{username:\"aaa\"},{username:'zhanfsan'}}").getValue(); 18 System.out.println("mList = " + mList+" \n "+map); 19 20 } 21 //输出结果 22 [1, 2, 3] 23 [1, 2, 3, 4] 24 [[123, 456], [789, 111]] 25 mList = [{username=aaa}, {username=zhanfsan}] 26 {username=tom, age=11}
4. 方法解析
在SpEL中,方法调用支持Java可访问的方法,包括对象方法,静态方法,支持可变方法参数;还可以使用String类型的所有可访问的方法,如String#substring()
修改User类:
1 public class User { 2 private String userName; 3 private Integer credits; 4 private Place place; 5 public String [] arr; 6 /** 7 * 添加三个方法 使用spel调用 8 * 共有方法 9 * 静态方法 10 * 私有方法 11 */ 12 public Boolean method1(String value){ 13 return value.equalsIgnoreCase("admin") ; 14 } 15 public static Boolean method2(String value){ 16 return value.equalsIgnoreCase("admin"); 17 } 18 private Boolean method3(String value){ 19 return value.equalsIgnoreCase("admin") 20 } 21 //setter getter 22 }