This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Framework 6.2.1!

Variables

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: $

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.

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

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

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.

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>

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)