javascript
Spring表达式语言(SPEL)学习(03)
rootObject
在表達(dá)式中直接寫(xiě)name和getName(),這時(shí)候Expression是無(wú)法解析的,因?yàn)槠洳恢纍ame和getName()對(duì)應(yīng)什么意思
@Test
public void test06() {
ExpressionParser parser = new SpelExpressionParser();
parser.parseExpression("name").getValue();
parser.parseExpression("getName()").getValue();
}
當(dāng)表達(dá)式是基于某一個(gè)對(duì)象時(shí),我們可以把對(duì)應(yīng)的對(duì)象作為一個(gè)rootObject傳遞給對(duì)應(yīng)的Experssion進(jìn)行取值
@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"));
}
設(shè)置上下文
通過(guò)指定EvaluationContext我們可以讓name和getName()變得有意義,指定了EvaluationContext之后,Expression將根據(jù)對(duì)應(yīng)的EvaluationContext來(lái)進(jìn)行解析
@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"));
}
設(shè)置變量
@Test
public void test14() {
Object user = new Object() {
public String getName() {
return "abc";
}
};
EvaluationContext context = new StandardEvaluationContext();
//1、設(shè)置變量
context.setVariable("user", user);
ExpressionParser parser = new SpelExpressionParser();
//2、表達(dá)式中以#varName的形式使用變量
Expression expression = parser.parseExpression("#user.name");
//3、在獲取表達(dá)式對(duì)應(yīng)的值時(shí)傳入包含對(duì)應(yīng)變量定義的EvaluationContext
String userName = expression.getValue(context, String.class);
//表達(dá)式中使用變量,并在獲取值時(shí)傳遞包含對(duì)應(yīng)變量定義的EvaluationContext。
Assert.assertTrue(userName.equals("abc"));
}
#root
root在表達(dá)式中永遠(yuǎn)都指向?qū)?yīng)EvaluationContext的rootObject對(duì)象
@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永遠(yuǎn)指向當(dāng)前對(duì)象,其通常用于集合類(lèi)型,表示集合中的一個(gè)元素
@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中選出為奇數(shù)的元素作為一個(gè)List進(jìn)行返回,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);
}
}
注冊(cè)方法
StandardEvaluationContext允許我們?cè)谄渲凶?cè)方法,然后在表達(dá)式中使用對(duì)應(yīng)的方法,注冊(cè)的方法必須是一個(gè)static類(lèi)型的公有方法。注冊(cè)方法是通過(guò)StandardEvaluationContext的registerFunction(funName,method)方法進(jìn)行。參數(shù)1表示需要在表達(dá)式中使用的方法名稱,參數(shù)2表示需要注冊(cè)的java.lang.reflect.Method。在表達(dá)式中可以使用類(lèi)似與#funName(params...)的形式來(lái)使用對(duì)應(yīng)的方法
static class MathUtils {
public static int plusTen(int i) {
return i+10;
}
}
@Test
public void test15() throws NoSuchMethodException, SecurityException {
ExpressionParser parser = new SpelExpressionParser();
//1、獲取需要設(shè)置的java.lang.reflect.Method,需是static類(lèi)型
Method plusTen = MathUtils.class.getDeclaredMethod("plusTen", int.class);
StandardEvaluationContext context = new StandardEvaluationContext();
//2、注冊(cè)方法到StandardEvaluationContext,第一個(gè)參數(shù)對(duì)應(yīng)表達(dá)式中需要使用的方法名
context.registerFunction("plusTen", plusTen);
//3、表達(dá)式中使用注冊(cè)的方法
Expression expression = parser.parseExpression("#plusTen(10)");
//4、傳遞包含對(duì)應(yīng)方法注冊(cè)的StandardEvaluationContext給Expression以獲取對(duì)應(yīng)的值
int result = expression.getValue(context, int.class);
Assert.assertTrue(result == 20);
}
賦值
SPEL支持給表達(dá)式賦值,其是通過(guò)Expression的setValue()方法進(jìn)行的,在賦值時(shí)需要指定rootObject或?qū)?yīng)的EvaluationContext
@Test
public void test() {
ExpressionParser parser = new SpelExpressionParser();
Date d = new Date();
Expression expression = parser.parseExpression("date");
//設(shè)日期為1號(hào) 此處為date,其原理是通過(guò)調(diào)用Date類(lèi)的setDate方法,必須指定是set開(kāi)頭的方法
expression.setValue(d, 1);
Object value = expression.getValue(d);
System.out.println(value);
//其原理是通過(guò)調(diào)用Date類(lèi)的setYear方法
expression = parser.parseExpression("year");
expression.setValue(d, 2023);
value = expression.getValue(d);
System.out.println(value);
}
對(duì)于List而言,在進(jìn)行賦值時(shí)是通過(guò)元素的索引進(jìn)行的,且對(duì)應(yīng)的索引是必須存在的
@Test
public void test09() {
ExpressionParser parser = new SpelExpressionParser();
List<Integer> list = new ArrayList<Integer>(1);
list.add(0);//添加一個(gè)元素0
EvaluationContext context = new StandardEvaluationContext();
//添加變量以方便表達(dá)式訪問(wèn)
context.setVariable("list", list);
//設(shè)置第一個(gè)元素的值為1
Expression expression = parser.parseExpression("#list[0]");
expression.setValue(context, 1);
int first = (Integer) expression.getValue(context);
System.out.println(first);
}
對(duì)于Map的賦值是通過(guò)key進(jìn)行的,對(duì)應(yīng)的key在Map中可以先不存在
@Test
public void test10() {
ExpressionParser parser = new SpelExpressionParser();
Map<String, Integer> map = new HashMap<>();
EvaluationContext context = new StandardEvaluationContext();
//添加變量以方便表達(dá)式訪問(wèn)
context.setVariable("map", map);
//設(shè)置第一個(gè)元素的值為1
Expression expression = parser.parseExpression("#map['key1']");
expression.setValue(context, 1);
int first = (Integer) expression.getValue(context);
System.out.println(first);
}
總結(jié)
以上是生活随笔為你收集整理的Spring表达式语言(SPEL)学习(03)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python 潮流周刊第 35 期(摘要
- 下一篇: 揭秘Spring事务失效场景分析与解决方