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

打印 上一主题 下一主题

主题 922|帖子 922|积分 2766

rootObject

在表达式中直接写name和getName(),这时候Expression是无法解析的,因为其不知道name和getName()对应什么意思
  1. @Test
  2. public void test06() {
  3.          ExpressionParser parser = new SpelExpressionParser();
  4.          parser.parseExpression("name").getValue();
  5.          parser.parseExpression("getName()").getValue();
  6. }
复制代码
当表达式是基于某一个对象时,我们可以把对应的对象作为一个rootObject传递给对应的Experssion进行取值
  1. @Test
  2. public void test07() {
  3.     Object user = new Object() {
  4.         public String getName() {
  5.                 return "abc";
  6.         }
  7.     };
  8.     ExpressionParser parser = new SpelExpressionParser();
  9.     Assert.assertTrue(parser.parseExpression("name").getValue(user, String.class).equals("abc"));
  10.     Assert.assertTrue(parser.parseExpression("getName()").getValue(user, String.class).equals("abc"));
  11. }
复制代码
设置上下文

通过指定EvaluationContext我们可以让name和getName()变得有意义,指定了EvaluationContext之后,Expression将根据对应的EvaluationContext来进行解析
  1. @Test
  2. public void test06() {
  3.     Object user = new Object() {
  4.     public String getName() {
  5.                 return "abc";
  6.         }
  7.     };
  8.     EvaluationContext context = new StandardEvaluationContext(user);
  9.     ExpressionParser parser = new SpelExpressionParser();
  10.     Assert.assertTrue(parser.parseExpression("name").getValue(context, String.class).equals("abc"));
  11.     Assert.assertTrue(parser.parseExpression("getName()").getValue(context, String.class).equals("abc"));
  12. }
复制代码
设置变量
  1. @Test
  2. public void test14() {
  3.     Object user = new Object() {
  4.         public String getName() {
  5.                 return "abc";
  6.         }
  7.     };
  8.     EvaluationContext context = new StandardEvaluationContext();
  9.     //1、设置变量
  10.     context.setVariable("user", user);
  11.     ExpressionParser parser = new SpelExpressionParser();
  12.     //2、表达式中以#varName的形式使用变量
  13.     Expression expression = parser.parseExpression("#user.name");
  14.     //3、在获取表达式对应的值时传入包含对应变量定义的EvaluationContext
  15.     String userName = expression.getValue(context, String.class);
  16.     //表达式中使用变量,并在获取值时传递包含对应变量定义的EvaluationContext。
  17.     Assert.assertTrue(userName.equals("abc"));
  18. }
复制代码
#root

root在表达式中永远都指向对应EvaluationContext的rootObject对象
  1. @Test
  2. public void test14_1() {
  3.     Object user = new Object() {
  4.         public String getName() {
  5.                 return "abc";
  6.         }
  7.     };
  8.     EvaluationContext context = new StandardEvaluationContext(user);
  9.     ExpressionParser parser = new SpelExpressionParser();
  10.         Assert.assertTrue(parser.parseExpression("#root.name").getValue(context).equals("abc"));
  11. }
复制代码
#this

this永远指向当前对象,其通常用于集合类型,表示集合中的一个元素
  1. @Test
  2. public void test14_2() {
  3.     ExpressionParser parser = new SpelExpressionParser();
  4.     List<Integer> intList = (List<Integer>)parser.parseExpression("{1,2,3,4,5,6}").getValue();
  5.     EvaluationContext context = new StandardEvaluationContext(intList);
  6.     //从List中选出为奇数的元素作为一个List进行返回,1、3、5。
  7.     List<Integer> oddList = (List<Integer>)parser.parseExpression("#root.?[#this%2==1]").getValue(context);
  8.     for (Integer odd : oddList) {
  9.             Assert.assertTrue(odd%2 == 1);
  10.     }
  11. }
复制代码
注册方法

StandardEvaluationContext允许我们在其中注册方法,然后在表达式中使用对应的方法,注册的方法必须是一个static类型的公有方法。注册方法是通过StandardEvaluationContext的registerFunction(funName,method)方法进行。参数1表示需要在表达式中使用的方法名称,参数2表示需要注册的java.lang.reflect.Method。在表达式中可以使用类似与#funName(params...)的形式来使用对应的方法
  1. static class MathUtils {
  2.     public static int plusTen(int i) {
  3.             return i+10;
  4.     }
  5. }
  6. @Test
  7. public void test15() throws NoSuchMethodException, SecurityException {
  8.     ExpressionParser parser = new SpelExpressionParser();
  9.     //1、获取需要设置的java.lang.reflect.Method,需是static类型
  10.     Method plusTen = MathUtils.class.getDeclaredMethod("plusTen", int.class);
  11.     StandardEvaluationContext context = new StandardEvaluationContext();
  12.     //2、注册方法到StandardEvaluationContext,第一个参数对应表达式中需要使用的方法名
  13.     context.registerFunction("plusTen", plusTen);
  14.     //3、表达式中使用注册的方法
  15.     Expression expression = parser.parseExpression("#plusTen(10)");
  16.     //4、传递包含对应方法注册的StandardEvaluationContext给Expression以获取对应的值
  17.     int result = expression.getValue(context, int.class);
  18.     Assert.assertTrue(result == 20);
  19. }
复制代码
赋值

SPEL支持给表达式赋值,其是通过Expression的setValue()方法进行的,在赋值时需要指定rootObject或对应的EvaluationContext
  1. @Test
  2. public void test() {
  3.     ExpressionParser parser = new SpelExpressionParser();
  4.     Date d = new Date();
  5.    
  6.     Expression expression = parser.parseExpression("date");
  7.     //设日期为1号 此处为date,其原理是通过调用Date类的setDate方法,必须指定是set开头的方法
  8.     expression.setValue(d, 1);
  9.     Object value = expression.getValue(d);
  10.     System.out.println(value);
  11.     //其原理是通过调用Date类的setYear方法
  12.     expression = parser.parseExpression("year");
  13.     expression.setValue(d, 2023);
  14.     value = expression.getValue(d);
  15.     System.out.println(value);
  16. }
复制代码
对于List而言,在进行赋值时是通过元素的索引进行的,且对应的索引是必须存在的
  1. @Test
  2. public void test09() {
  3.     ExpressionParser parser = new SpelExpressionParser();
  4.     List<Integer> list = new ArrayList<Integer>(1);
  5.     list.add(0);//添加一个元素0
  6.     EvaluationContext context = new StandardEvaluationContext();
  7.     //添加变量以方便表达式访问
  8.     context.setVariable("list", list);
  9.     //设置第一个元素的值为1
  10.     Expression expression = parser.parseExpression("#list[0]");
  11.     expression.setValue(context, 1);
  12.     int first = (Integer) expression.getValue(context);
  13.     System.out.println(first);
  14. }
复制代码
对于Map的赋值是通过key进行的,对应的key在Map中可以先不存在
  1. @Test
  2. public void test10() {
  3.     ExpressionParser parser = new SpelExpressionParser();
  4.     Map<String, Integer> map = new HashMap<>();
  5.     EvaluationContext context = new StandardEvaluationContext();
  6.     //添加变量以方便表达式访问
  7.     context.setVariable("map", map);
  8.     //设置第一个元素的值为1
  9.     Expression expression = parser.parseExpression("#map['key1']");
  10.     expression.setValue(context, 1);
  11.     int first = (Integer) expression.getValue(context);
  12.     System.out.println(first);
  13. }
复制代码

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

麻花痒

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表