变量

您可以使用#variableName语法在表达式中引用变量。通过在EvaluationContext实现中使用setVariable()方法来设置变量。

变量名必须以字母(如下所定义)、下划线或美元符号开头。

变量名必须由以下支持的字符类型之一组成。

  • 字母:任何使java.lang.Character.isLetter(char)返回true的字符

    • 这包括诸如AZazüñé等字母,以及其他字符集(如中文、日文、西里尔文等)中的字母。

  • 数字:09

  • 下划线:_

  • 美元符号:$

EvaluationContext中设置变量或根上下文对象时,建议变量或根上下文对象的类型为public

否则,涉及具有非公共类型的变量或根上下文对象的某些类型的SpEL表达式可能无法评估或编译。

由于变量与 函数在评估上下文中共享一个公共命名空间,因此必须确保变量名和函数名不重叠。

以下示例展示了如何使用变量。

  • Java

  • Kotlin

Inventor tesla = new Inventor("Nikola Tesla", "Serbian");

EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
context.setVariable("newName", "Mike Tesla");

parser.parseExpression("name = #newName").getValue(context, tesla);
System.out.println(tesla.getName());  // "Mike Tesla"
val tesla = Inventor("Nikola Tesla", "Serbian")

val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
context.setVariable("newName", "Mike Tesla")

parser.parseExpression("name = #newName").getValue(context, tesla)
println(tesla.name)  // "Mike Tesla"

#this#root变量

#this变量始终被定义,并引用当前评估对象(未经限定引用解析的对象)。#root变量始终被定义,并引用根上下文对象。尽管#this在评估表达式的组件时可能会变化,但#root始终指向根对象。

以下示例展示了如何在与集合选择结合使用#this变量。

  • Java

  • Kotlin

// 创建一个素数整数列表。
List<Integer> primes = List.of(2, 3, 5, 7, 11, 13, 17);

// 创建解析器并将变量'primes'设置为整数列表。
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
context.setVariable("primes", primes);

// 从列表中选择所有大于10的素数(使用选择 ?{...})。
String expression = "#primes.?[#this > 10]";

// 评估为包含[11, 13, 17]的列表。
List<Integer> primesGreaterThanTen =
		parser.parseExpression(expression).getValue(context, List.class);
// 创建一个素数整数列表。
val primes = listOf(2, 3, 5, 7, 11, 13, 17)

// 创建解析器并将变量'primes'设置为整数列表。
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
context.setVariable("primes", primes)

// 从列表中选择所有大于10的素数(使用选择 ?{...})。
val expression = "#primes.?[#this > 10]"

// 评估为包含[11, 13, 17]的列表。
val primesGreaterThanTen = parser.parseExpression(expression)
		.getValue(context) as List<Int>

以下示例展示了如何在与集合投影结合使用#this#root变量。

  • Java

  • Kotlin

// 创建解析器和评估上下文。
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();

// 创建一个发明家作为根上下文对象。
Inventor tesla = new Inventor("Nikola Tesla");
tesla.setInventions("Telephone repeater", "Tesla coil transformer");

// 遍历作为#root对象引用的发明家的所有发明,并生成一个字符串列表,其内容采用“<发明家的姓名>发明了<发明>。”的形式(使用投影 !{...})。
String expression = "#root.inventions.![#root.name + '发明了' + #this + '.']";

// 评估为包含:
// "Nikola Tesla发明了Telephone repeater."
// "Nikola Tesla发明了Tesla coil transformer."
List<String> results = parser.parseExpression(expression)
		.getValue(context, tesla, List.class);
// 创建解析器和评估上下文。
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()

// 创建一个发明家作为根上下文对象。
val tesla = Inventor("Nikola Tesla")
tesla.setInventions("Telephone repeater", "Tesla coil transformer")

// 遍历作为#root对象引用的发明家的所有发明,并生成一个字符串列表,其内容采用“<发明家的姓名>发明了<发明>。”的形式(使用投影 !{...})。
val expression = "#root.inventions.![#root.name + '发明了' + #this + '.']"

// 评估为包含:
// "Nikola Tesla发明了Telephone repeater."
// "Nikola Tesla发明了Tesla coil transformer."
val results = parser.parseExpression(expression)
		.getValue(context, tesla, List::class.java)