javascript
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);
}
總結
以上是生活随笔為你收集整理的Spring表达式语言(SPEL)学习(03)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python 潮流周刊第 35 期(摘要
- 下一篇: 从Bitcask存储模型谈超轻量级KV系