036SpEL表达式

本文介绍了Spring Expression Language (SpEL)的核心组件,包括ExperssionParser、Expression和EvaluationContext接口。SpEL提供了丰富的功能,如解析字符串为Expression对象,通过不同方法获取表达式值,以及在EvaluationContext中设置变量和根对象。通过示例代码,文章展示了SpEL的全面用法和关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpEL主要提供如下三个接口:

  • ExperssionParser : 该接口中的实例方法parseExpression(String str)负责将字符串str解析,返回Expression 对象。
  • Expression 该接口实例代表一个表达式
  • EvaluationContext : 计算表达式上下文,类似于ApplicationContext功能

三个接口中的主要方法:

  1. ExperssionParser中有方法:
    Expression parseExpression(String str): 负责将字符串str解析,返回Expression 对象。

  2. Expression中有方法:
    Object getValue(): 计算表达式的值。
    <T> T getValue(Class<T> desiredResultType): 计算表达式的值,并尝试吧表达式的值当成指定类型来处理。

    Object getValue(EvaluationContext context): 用指定的EvaluationContext 计算表达式的值。
    <T> T getValue(EvaluationContext context, Class<T> desiredResultType): 用指定的EvaluationContext 计算表达式的值,并尝试吧表达式的值当成指定类型来处理。

    Object getValue(Object rootObject): 以rootObject作为表达式的root对象来计算表达式的值。
    <T> T getValue(Object rootObject,Class<T> desiredResultType): 以rootObject作为表达式的root对象来计算表达式的值,并尝试吧表达式的值当成指定类型来处理。

  3. EvaluationContext中有方法:
    void setVariable(String name,Object value):向EvaluationContext中添加新的对象
    void setRootObject(Object rootObject):设置EvaluationContext的rootObject,在SpEL访问root对象的属性时,可以省略root对象前缀

下面程序演示了比较全面的SpEL的详细用法,以及一些知识点说明

public class SpELTest
{
    public static void main(String[] args)
    {
        //表达式解析器
        SpelExpressionParser parser =  new SpelExpressionParser();
        //直接量表达式
        Expression ex = parser.parseExpression("'Hello world!'");
        System.out.println(ex.getValue());//Hello world!
        ex = parser.parseExpression("0.2");
        System.out.println(ex.getValue(Double.class));//0.2

        //list集合
        ex = parser.parseExpression("{56,'哈哈啊哈',{'嵌套list',666}}");
        System.out.println(ex.getValue());//[56, 哈哈啊哈, [嵌套list, 666]]

        //数组
        ex = parser.parseExpression("new String[]{'孙悟空','沙和尚','猪八戒'}");
        System.out.println(ex.getValue());//[Ljava.lang.String;@7a220c9a

        //访问List、Map等集合的元素
        var list = List.of("白云","大地",45);
        var map = Map.of("语文",59,"数学",66,"英语",15);
        //创建容器,相当于传统的ApplicationContext
        StandardEvaluationContext ctx = new StandardEvaluationContext();
        //向容器中添加变量,相当于传统的在ApplicationContext中添加bean元素
        ctx.setVariable("li",list);
        ctx.setVariable("ma",map);
        //#表示该变量是在容器中的
        ex = parser.parseExpression("#li[1]");
        //在getValue中指定容器
        System.out.println(ex.getValue(ctx));//大地
        ex = parser.parseExpression("#ma['英语']");
        System.out.println(ex.getValue(ctx));//15

        //调用方法
        ctx.setVariable("str","ABCDE");
        ex = parser.parseExpression("#str.length()");
        System.out.println(ex.getValue(ctx));//5

        //算数运算符、比较运算符、逻辑运算符、赋值运算符、三目运算符
        ex = parser.parseExpression("15+15/5 > 17");
        System.out.println(ex.getValue());//true
        ctx.setVariable("num",5);
        ex = parser.parseExpression("#num = #num + 1");
        System.out.println(ex.getValue(ctx));//6
        ex = parser.parseExpression("#num==6? 'num等于6' : 'num不等于6' ");
        System.out.println(ex.getValue(ctx));//num等于6

        //类型运算符
        //T()告诉SpEl把它当成一个类来处理,而不是其他解析
        ex = parser.parseExpression("T(java.lang.System).getProperty('os.name')");
        System.out.println(ex.getValue());//Windows 10

        //调用构造器
        ex = parser.parseExpression("new java.util.Date()");
        System.out.println(ex.getValue());//Sat Aug 15 11:47:06 CST 2020

        //SpEL特殊变量
        //#this:引用SpEl正在计算的对象
        //#root:引用SpEL的容器的root对象,容器的方法setRootObject用来设置容器唯一的root

        //自定义函数,实质就是引入方法并且重命名方法名
        //容器StandardEvaluationContext中的方法:
        //registerFunction(String newName,Method m):将m方法在容器中注册成自定义函数
        //该功能意义不大

        //安全导航
        //?表示如果aaa不为null就访问aaa.bbb,否则只会访问aaa不会往下访问bbb(ctx中没有aaa变量)
        ex = parser.parseExpression("#aaa?.bbbb");
        System.out.println(ex.getValue(ctx));//null
//        ex = parser.parseExpression("#aaa.bbbb");
//        System.out.println(ex.getValue(ctx));//空指针异常

        //集合元素选择(集合元素筛选)
        //语法:collection.?[condition_expr]
        var list2 = List.of("德玛西亚","守望之海","祖安");
        ctx.setVariable("li2",list2);
        ex = parser.parseExpression("#li2.?[length() < 4]");
        System.out.println(ex.getValue(ctx));//[祖安]

        //集合投影运算(对集合元素进行处理,然后把处理后的值替换掉原来的值返回)
        var list3 = List.of("皮城女警","未来守护者","诺克萨斯之手");
        ctx.setVariable("li3",list3);
        ex = parser.parseExpression("#li3.![length()]");
        System.out.println(ex.getValue(ctx));//[4, 5, 6]
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值