Spring el表达式的进阶使用

Spring基本篇
placeholder image
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 = , 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.
classnew 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));
    }

}

运行结果

image.png

说明

(1)上述代码中的testRegisterBatchFunction函数旨在注册类的批量函数,使得使用更加方便,但无法运行成功,看着没问题,但似乎不是这么使用的;

(2)在调用自定义函数(方法)时,也可以是静态方法,但只能是public的;


 点赞


 发表评论

当前回复:作者

 评论列表


留言区