Spring表达式语言(SPEL)(03)

rootObject

在表达式中直接写name和getName(),这时候Expression是无法解析的,因为其不知道name和getName()对应什么意思

@Test
public void test06() {
	 ExpressionParser parser = new SpelExpressionParser();
	 parser.parseExpression("name").getValue();
	 parser.parseExpression("getName()").getValue();
}

当表达式是基于某一个对象时,我们可以把对应的对象作为一个rootObject传递给对应的Experssion进行取值

@Test
public void test07() {
    Object user = new Object() {
        public String getName() {
        	return "abc";
        }
    };
    ExpressionParser parser = new SpelExpressionParser();
    Assert.assertTrue(parser.parseExpression("name").getValue(user, String.class).equals("abc"));
    Assert.assertTrue(parser.parseExpression("getName()").getValue(user, String.class).equals("abc"));
}

设置上下文

通过指定EvaluationContext我们可以让name和getName()变得有意义,指定了EvaluationContext之后,Expression将根据对应的EvaluationContext来进行解析

@Test
public void test06() {
    Object user = new Object() {
    public String getName() {
        	return "abc";
        }
    };
    EvaluationContext context = new StandardEvaluationContext(user);
    ExpressionParser parser = new SpelExpressionParser();
    Assert.assertTrue(parser.parseExpression("name").getValue(context, String.class).equals("abc"));
    Assert.assertTrue(parser.parseExpression("getName()").getValue(context, String.class).equals("abc"));
}

设置变量

@Test
public void test14() {
    Object user = new Object() {
        public String getName() {
        	return "abc";
        }
    };
    EvaluationContext context = new StandardEvaluationContext();
    //1、设置变量
    context.setVariable("user", user);
    ExpressionParser parser = new SpelExpressionParser();
    //2、表达式中以#varName的形式使用变量
    Expression expression = parser.parseExpression("#user.name");
    //3、在获取表达式对应的值时传入包含对应变量定义的EvaluationContext
    String userName = expression.getValue(context, String.class);
    //表达式中使用变量,并在获取值时传递包含对应变量定义的EvaluationContext。
    Assert.assertTrue(userName.equals("abc"));
}

#root

#root在表达式中永远都指向对应EvaluationContext的rootObject对象

@Test
public void test14_1() {
    Object user = new Object() {
        public String getName() {
        	return "abc";
        }
    };
    EvaluationContext context = new StandardEvaluationContext(user);
    ExpressionParser parser = new SpelExpressionParser();
 	Assert.assertTrue(parser.parseExpression("#root.name").getValue(context).equals("abc"));
}

#this

#this永远指向当前对象,其通常用于集合类型,表示集合中的一个元素

@Test
public void test14_2() {
    ExpressionParser parser = new SpelExpressionParser();
    List<Integer> intList = (List<Integer>)parser.parseExpression("{1,2,3,4,5,6}").getValue();
    EvaluationContext context = new StandardEvaluationContext(intList);
    //从List中选出为奇数的元素作为一个List进行返回,1、3、5。
    List<Integer> oddList = (List<Integer>)parser.parseExpression("#root.?[#this%2==1]").getValue(context);
    for (Integer odd : oddList) {
    	Assert.assertTrue(odd%2 == 1);
    }
}

注册方法

StandardEvaluationContext允许我们在其中注册方法,然后在表达式中使用对应的方法,注册的方法必须是一个static类型的公有方法。注册方法是通过StandardEvaluationContext的registerFunction(funName,method)方法进行。参数1表示需要在表达式中使用的方法名称,参数2表示需要注册的java.lang.reflect.Method。在表达式中可以使用类似与#funName(params…)的形式来使用对应的方法

static class MathUtils {
    public static int plusTen(int i) {
    	return i+10;
    }
}
 
@Test
public void test15() throws NoSuchMethodException, SecurityException {
    ExpressionParser parser = new SpelExpressionParser();
    //1、获取需要设置的java.lang.reflect.Method,需是static类型
    Method plusTen = MathUtils.class.getDeclaredMethod("plusTen", int.class);
    StandardEvaluationContext context = new StandardEvaluationContext();
    //2、注册方法到StandardEvaluationContext,第一个参数对应表达式中需要使用的方法名
    context.registerFunction("plusTen", plusTen);
    //3、表达式中使用注册的方法
    Expression expression = parser.parseExpression("#plusTen(10)");
    //4、传递包含对应方法注册的StandardEvaluationContext给Expression以获取对应的值
    int result = expression.getValue(context, int.class);
    Assert.assertTrue(result == 20);
}

赋值

SPEL支持给表达式赋值,其是通过Expression的setValue()方法进行的,在赋值时需要指定rootObject或对应的EvaluationContext

@Test
public void test() {
    ExpressionParser parser = new SpelExpressionParser();
    Date d = new Date();
    
    Expression expression = parser.parseExpression("date");
    //设日期为1号 此处为date,其原理是通过调用Date类的setDate方法,必须指定是set开头的方法
    expression.setValue(d, 1);
    Object value = expression.getValue(d);
    System.out.println(value);

    //其原理是通过调用Date类的setYear方法
    expression = parser.parseExpression("year");
    expression.setValue(d, 2023);
    value = expression.getValue(d);
    System.out.println(value);
}

对于List而言,在进行赋值时是通过元素的索引进行的,且对应的索引是必须存在的

@Test
public void test09() {
    ExpressionParser parser = new SpelExpressionParser();
    List<Integer> list = new ArrayList<Integer>(1);
    list.add(0);//添加一个元素0
    EvaluationContext context = new StandardEvaluationContext();
    //添加变量以方便表达式访问
    context.setVariable("list", list);
    //设置第一个元素的值为1
    Expression expression = parser.parseExpression("#list[0]");
    expression.setValue(context, 1);
    int first = (Integer) expression.getValue(context);
    System.out.println(first);
}

对于Map的赋值是通过key进行的,对应的key在Map中可以先不存在

@Test
public void test10() {
    ExpressionParser parser = new SpelExpressionParser();
    Map<String, Integer> map = new HashMap<>();
    EvaluationContext context = new StandardEvaluationContext();
    //添加变量以方便表达式访问
    context.setVariable("map", map);
    //设置第一个元素的值为1
    Expression expression = parser.parseExpression("#map['key1']");
    expression.setValue(context, 1);
    int first = (Integer) expression.getValue(context);
    System.out.println(first);
}

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring表达式语言SpEL)是一种强大的表达式语言,用于在运行时计算表达式的值。SpEL可以用于配置文件、注解和代码中,支持对Bean的属性、方法和构造函数进行访问和操作,提供了很多常用的运算符和函数,是Spring框架中非常重要的一部分。 SpEL支持以下特性: 1. 引用Bean的属性和方法。可以使用“#”符号引用Bean的属性和方法,如“#user.name”表示引用名为user的Bean的name属性。 2. 调用静态方法和常量。可以使用“T()”关键字调用静态方法和常量,如“T(java.lang.Math).PI”表示引用Math类的PI常量。 3. 访问数组和集合。可以使用“[]”符号访问数组和集合,如“list[0]”表示访问名为list的集合的第一个元素。 4. 进行算术运算和比较运算。SpEL支持常见的算术运算和比较运算符,如“+”、“-”、“*”、“/”、“%”、“==”、“!=”、“<”、“>”等。 5. 定义变量和使用占位符。可以使用“#{}”定义变量和使用占位符,如“#{T(System).currentTimeMillis()}”表示定义一个名为currentTimeMillis的变量并赋值为当前时间的毫秒数。 6. 调用Bean的构造函数。可以使用“new”关键字调用Bean的构造函数,如“new java.util.Date()”表示调用java.util.Date类的无参构造函数。 SpEL可以在Spring的XML配置文件、@Value注解以及SpEL表达式注解中使用,可以方便地实现复杂的条件判断和动态计算。例如,可以使用SpEL表达式注解来实现@Scheduled注解的cron表达式的动态计算,或者在XML配置文件中使用SpEL表达式来实现Bean之间的依赖注入和条件配置等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值