Spring el表达式的进阶使用
Spring基本篇admin 发布于:2019-04-05 08:45:19
阅读:loading
本篇文章中摘取了一些个人认为可能是会常用到的实现,主要是spel的数组应用、集合应用、方法应用、自定义方法应用等,然而它的强大不仅限于此,只是使用贵在引导。
数组应用:长度获取、下标值获取、数组对象的函数使用,东西比较简单,详细如下:
集合应用:List<Integer>结构、List<Map<Object , Object>>结构、List的新增、修改、删除;
方法应用:同java中实际类型的对象等同,可直接调用其对应的函数,以substring函数为例;
自定义方法:直接设置对象并调用其自身函数、直接使用new构造对象并调用、注册函数方法使用、注册类的批量函数实现;
package cn.chendd;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.junit.Test;
import org.springframework.expression.MethodFilter;
import org.springframework.expression.MethodResolver;
import org.springframework.expression.spel.support.ReflectiveMethodResolver;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import java.awt.*;
import java.lang.reflect.Method;
import java.util.*;
import java.util.List;
public class AdvanceSpringElTest extends SimpleSpringElTest {
/**
* 数组示例
*/
@Test
public void testArray(){
String dataArray[] = {"a" , "b" , "c" , "d" , "e"};
set("dataArray" , dataArray);
String evalLens = "#dataArray.length";//取得数组长度
Integer lens = get(evalLens , Integer.class);
System.out.println("数组长度:" + lens);
String evalItem = "#dataArray[2]";
String item = get(evalItem , String.class);
System.out.println("数组下标值:" + item);
String evalItemUpper = evalItem + ".toUpperCase()";
String itemUpper = get(evalItemUpper , String.class);
System.out.println("数组下标值转大写:" + itemUpper);
String eval = "'字符串常量拼接:' + #dataArray.toString()";
System.out.println(get(eval , String.class));
}
@Test
public void testList(){
List list1 = get("{10 , 20 , 30 , 40 , 50}" , List.class);
System.out.println("构造一个集合:" + list1);
List list2 = get("{{x:1,y:2},{x:'A',y:'B'}}" , List.class);
System.out.println("构造一个对象集合:" + list2);
for (int i = 0; i < list2.size(); i++) {
Map map = (Map) list2.get(i);
//类的字节码:Collections$UnmodifiableMap
System.out.println(map.getClass() + " , "
+ map.get("x").getClass() + " , "
+ map.get("y").getClass());
}
//新增一条数据
set("list2" , list2);
String add = "#list2.add({x:3,y:4})";
Boolean addFlag = get(add , Boolean.class);
System.out.println(addFlag ? "新增成功" : "未新增");
System.out.println("新增后的集合:" + list2);
//修改一条数据
String update = "#list2.set(2,{x:'C',y:'D'})";
get(update , Object.class);
System.out.println("修改后的集合:" + list2);
//删除一条数据(使用remove(Object)函数删除)
Map<String , Object> deleteItem = new HashMap<String , Object>();
deleteItem.put("x" , "C");
deleteItem.put("y" , "D");
set("deleteItem" , deleteItem).set("itemIndex" , 0);
String delete = "#list2.remove(#deleteItem)";
get(delete , Object.class);
System.out.println("对象方式删除后的集合:" + list2);
//删除一条数据(使用索引删除)---删除不了
get("#list2.remove(#itemIndex)" , Object.class);
System.out.println("索引方式删除后的集合:" + list2);
}
/**
* 变量使用函数+函数使用变量参数
*/
@Test
public void testStringFunction(){
int start = 4 , end = start + 6;
set("start" , start).set("end" , end).set("name" , "www.chendd.cn");
String eval = "#name.substring(#start , #end)";
String value = get(eval, String.class);
System.out.println("变量使用函数+函数使用变量参数:" + value);
}
/**
* 注册方法使用
*/
@Test
public void testCustomFunction(){
set("test" , this);
String eval = "#test.getPoint()";
Point point = get(eval , Point.class);
System.out.println("调用自定义方法一:" + point.getX() + " , " + point.getY());
Point newPoint = get("new cn.chendd.AdvanceSpringElTest().getRandomPoint()" , Point.class);
System.out.println("调用自定义方法二:" + newPoint.getX() + " , " + newPoint.getY());
set("date" , new Date()).set("year" , 100).set("month" , 4).set("date" , 20);
String evalDate = "new java.util.Date(#year , #month , #date)";
Date date = get(evalDate , Date.class);
System.out.println(date.toString());
//说明:standContext的注册函数另外一种:registerFunction
}
/**
* 注册方法使用
*/
@Test
public void testRegisterFunction(){
StandardEvaluationContext standContext = (StandardEvaluationContext) context;
String name = "upperCase";
Method upperCase = MethodUtils.getAccessibleMethod(StringUtils.class, name, String.class);
standContext.registerFunction(name, upperCase);
set("name", "hello world");
String eval = "#upperCase('Java ' + #name)";
String value = get(eval, String.class);
System.out.println(value);
}
/**
* 批量注册方法
* @deprecated 存在问题,批量注册方法
*/
@Test
public void testRegisterBatchFunction() throws Exception{
StandardEvaluationContext standContext = (StandardEvaluationContext) context;
ReflectiveMethodResolver mr = new ReflectiveMethodResolver();
mr.registerMethodFilter(StringUtils.class, new MethodFilter() {
@Override
public List<Method> filter(List<Method> methods) {
for (Method method : methods) {
standContext.registerFunction(method.getName(), method);
}
return methods;
}
});
List<MethodResolver> mrsList = standContext.getMethodResolvers();
mrsList.add(mr);
standContext.setMethodResolvers(mrsList);
Object value = parser.parseExpression("#length('Java')").getValue(standContext);
System.out.println(value);
}
/**
* 自定义方法
* @return 坐标对象
*/
public Point getPoint(){
return new Point(100 , 200);
}
/**
* 自定义方法
* @return 坐标对象
*/
public Point getRandomPoint(){
Random random = new Random();
return new Point(random.nextInt(100) , random.nextInt(200));
}
}
(1)上述代码中的testRegisterBatchFunction函数旨在注册类的批量函数,使得使用更加方便,但无法运行成功,看着没问题,但似乎不是这么使用的;
(2)在调用自定义函数(方法)时,也可以是静态方法,但只能是public的;
点赞