Variables

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

You can reference variables in an expression by using the #variableName syntax. Variables are set by using the setVariable() method in EvaluationContext implementations.

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

Variable names must be begin with a letter (as defined below), an underscore, or a dollar sign.

变量名称必须由以下受支持的字符类型中的一个或多个组成。

Variable names must be composed of one or more of the following supported types of characters.

  • letter: any character for which java.lang.Character.isLetter(char) returns true

    • This includes letters such as A to Z, a to z, ü, ñ, and é as well as letters from other character sets such as Chinese, Japanese, Cyrillic, etc.

  • digit: 0 to 9

  • underscore: _

  • dollar sign: $

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

When setting a variable or root context object in the EvaluationContext, it is advised that the type of the variable or root context object be public.

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

Otherwise, certain types of SpEL expressions involving a variable or root context object with a non-public type may fail to evaluate or compile.

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

Since variables share a common namespace with functions in the evaluation context, care must be taken to ensure that variable names and functions names do not overlap.

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

The following example shows how to use variables.

  • 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"

The #this and #root Variables

#this 变量始终定义,并且引用当前评估对象(根据该对象解析不合格引用)。#root 变量始终定义,并且引用根上下文对象。虽然在评估表达式的组件时 #this 可能变化,但 #root 始终引用根。

The #this variable is always defined and refers to the current evaluation object (against which unqualified references are resolved). The #root variable is always defined and refers to the root context object. Although #this may vary as components of an expression are evaluated, #root always refers to the root.

以下示例显示如何将 #this 变量与 collection selection 结合使用。

The following example shows how to use the #this variable in conjunction with collection selection.

  • Java

  • Kotlin

// Create a list of prime integers.
List<Integer> primes = List.of(2, 3, 5, 7, 11, 13, 17);

// Create parser and set variable 'primes' as the list of integers.
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();
context.setVariable("primes", primes);

// Select all prime numbers > 10 from the list (using selection ?{...}).
String expression = "#primes.?[#this > 10]";

// Evaluates to a list containing [11, 13, 17].
List<Integer> primesGreaterThanTen =
		parser.parseExpression(expression).getValue(context, List.class);
// Create a list of prime integers.
val primes = listOf(2, 3, 5, 7, 11, 13, 17)

// Create parser and set variable 'primes' as the list of integers.
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()
context.setVariable("primes", primes)

// Select all prime numbers > 10 from the list (using selection ?{...}).
val expression = "#primes.?[#this > 10]"

// Evaluates to a list containing [11, 13, 17].
val primesGreaterThanTen = parser.parseExpression(expression)
		.getValue(context) as List<Int>

以下示例显示如何将 #this#root 变量与 collection projection 结合使用。

The following example shows how to use the #this and #root variables together in conjunction with collection projection.

  • Java

  • Kotlin

// Create parser and evaluation context.
ExpressionParser parser = new SpelExpressionParser();
EvaluationContext context = SimpleEvaluationContext.forReadWriteDataBinding().build();

// Create an inventor to use as the root context object.
Inventor tesla = new Inventor("Nikola Tesla");
tesla.setInventions("Telephone repeater", "Tesla coil transformer");

// Iterate over all inventions of the Inventor referenced as the #root
// object, and generate a list of strings whose contents take the form
// "<inventor's name> invented the <invention>." (using projection !{...}).
String expression = "#root.inventions.![#root.name + ' invented the ' + #this + '.']";

// Evaluates to a list containing:
// "Nikola Tesla invented the Telephone repeater."
// "Nikola Tesla invented the Tesla coil transformer."
List<String> results = parser.parseExpression(expression)
		.getValue(context, tesla, List.class);
// Create parser and evaluation context.
val parser = SpelExpressionParser()
val context = SimpleEvaluationContext.forReadWriteDataBinding().build()

// Create an inventor to use as the root context object.
val tesla = Inventor("Nikola Tesla")
tesla.setInventions("Telephone repeater", "Tesla coil transformer")

// Iterate over all inventions of the Inventor referenced as the #root
// object, and generate a list of strings whose contents take the form
// "<inventor's name> invented the <invention>." (using projection !{...}).
val expression = "#root.inventions.![#root.name + ' invented the ' + #this + '.']"

// Evaluates to a list containing:
// "Nikola Tesla invented the Telephone repeater."
// "Nikola Tesla invented the Tesla coil transformer."
val results = parser.parseExpression(expression)
		.getValue(context, tesla, List::class.java)