0
# Spring Expression Language (SpEL)
1
2
The Spring Expression Language (SpEL) is a powerful expression language that supports querying and manipulating an object graph at runtime. It offers many features including method invocation, accessing/setting properties, array/collection/map indexing, conditional operators, variables, user-defined functions, and more.
3
4
## Package Information
5
6
```xml
7
<dependency>
8
<groupId>org.springframework</groupId>
9
<artifactId>spring-expression</artifactId>
10
<version>6.2.8</version>
11
</dependency>
12
```
13
14
**Gradle:**
15
```gradle
16
implementation 'org.springframework:spring-expression:6.2.8'
17
```
18
19
## Core Imports
20
21
```java
22
// Core expression interfaces
23
import org.springframework.expression.Expression;
24
import org.springframework.expression.ExpressionParser;
25
import org.springframework.expression.EvaluationContext;
26
import org.springframework.expression.ParserContext;
27
28
// Standard SpEL implementation
29
import org.springframework.expression.spel.standard.SpelExpressionParser;
30
import org.springframework.expression.spel.standard.SpelExpression;
31
32
// Evaluation contexts
33
import org.springframework.expression.spel.support.StandardEvaluationContext;
34
import org.springframework.expression.spel.support.SimpleEvaluationContext;
35
36
// Configuration
37
import org.springframework.expression.spel.SpelParserConfiguration;
38
import org.springframework.expression.spel.SpelCompilerMode;
39
40
// Value types
41
import org.springframework.expression.TypedValue;
42
import org.springframework.core.convert.TypeDescriptor;
43
44
// Exceptions
45
import org.springframework.expression.ExpressionException;
46
import org.springframework.expression.EvaluationException;
47
import org.springframework.expression.ParseException;
48
```
49
{ .api }
50
51
## Basic Usage
52
53
### Simple Expression Evaluation
54
55
```java
56
ExpressionParser parser = new SpelExpressionParser();
57
Expression exp = parser.parseExpression("'Hello World'");
58
String message = (String) exp.getValue();
59
// Returns: "Hello World"
60
61
// Mathematical expressions
62
Expression mathExp = parser.parseExpression("2 + 3 * 4");
63
Integer result = mathExp.getValue(Integer.class);
64
// Returns: 14
65
```
66
{ .api }
67
68
### Expression with Object Context
69
70
```java
71
public class Person {
72
private String name;
73
private int age;
74
// getters and setters...
75
}
76
77
Person person = new Person();
78
person.setName("John");
79
person.setAge(30);
80
81
ExpressionParser parser = new SpelExpressionParser();
82
Expression exp = parser.parseExpression("name");
83
String name = exp.getValue(person, String.class);
84
// Returns: "John"
85
86
// Property navigation
87
exp = parser.parseExpression("name.length()");
88
Integer length = exp.getValue(person, Integer.class);
89
// Returns: 4
90
```
91
{ .api }
92
93
### Template Expressions
94
95
```java
96
ExpressionParser parser = new SpelExpressionParser();
97
Expression exp = parser.parseExpression(
98
"Hello #{name}, you are #{age} years old!",
99
ParserContext.TEMPLATE_EXPRESSION
100
);
101
102
EvaluationContext context = SimpleEvaluationContext.forReadOnlyDataBinding().build();
103
String message = exp.getValue(context, person, String.class);
104
// Returns: "Hello John, you are 30 years old!"
105
```
106
{ .api }
107
108
## Architecture
109
110
SpEL's architecture is built around several core abstractions:
111
112
- **ExpressionParser**: Parses expression strings into executable expressions
113
- **Expression**: Represents a compiled expression ready for evaluation
114
- **EvaluationContext**: Provides the context for expression evaluation (variables, functions, resolvers)
115
- **Accessors & Resolvers**: Strategy interfaces for extending SpEL's capabilities
116
117
The standard implementation uses reflection-based resolvers and supports compilation to bytecode for improved performance.
118
119
## Core Expression Functionality
120
121
### ExpressionParser Interface
122
123
```java
124
public interface ExpressionParser {
125
Expression parseExpression(String expressionString)
126
throws ParseException;
127
Expression parseExpression(String expressionString, ParserContext context)
128
throws ParseException;
129
}
130
```
131
{ .api }
132
133
### Expression Interface
134
135
```java
136
public interface Expression {
137
String getExpressionString();
138
139
// getValue methods
140
Object getValue() throws EvaluationException;
141
<T> T getValue(Class<T> desiredResultType) throws EvaluationException;
142
Object getValue(Object rootObject) throws EvaluationException;
143
<T> T getValue(Object rootObject, Class<T> desiredResultType) throws EvaluationException;
144
Object getValue(EvaluationContext context) throws EvaluationException;
145
<T> T getValue(EvaluationContext context, Class<T> desiredResultType) throws EvaluationException;
146
Object getValue(EvaluationContext context, Object rootObject) throws EvaluationException;
147
<T> T getValue(EvaluationContext context, Object rootObject, Class<T> desiredResultType)
148
throws EvaluationException;
149
150
// getValueType methods
151
Class<?> getValueType() throws EvaluationException;
152
Class<?> getValueType(Object rootObject) throws EvaluationException;
153
Class<?> getValueType(EvaluationContext context) throws EvaluationException;
154
Class<?> getValueType(EvaluationContext context, Object rootObject) throws EvaluationException;
155
156
// getValueTypeDescriptor methods
157
TypeDescriptor getValueTypeDescriptor() throws EvaluationException;
158
TypeDescriptor getValueTypeDescriptor(Object rootObject) throws EvaluationException;
159
TypeDescriptor getValueTypeDescriptor(EvaluationContext context) throws EvaluationException;
160
TypeDescriptor getValueTypeDescriptor(EvaluationContext context, Object rootObject)
161
throws EvaluationException;
162
163
// isWritable methods
164
boolean isWritable(Object rootObject) throws EvaluationException;
165
boolean isWritable(EvaluationContext context) throws EvaluationException;
166
boolean isWritable(EvaluationContext context, Object rootObject) throws EvaluationException;
167
168
// setValue methods
169
void setValue(Object rootObject, Object value) throws EvaluationException;
170
void setValue(EvaluationContext context, Object value) throws EvaluationException;
171
void setValue(EvaluationContext context, Object rootObject, Object value)
172
throws EvaluationException;
173
}
174
```
175
{ .api }
176
177
### TypedValue Class
178
179
```java
180
public class TypedValue {
181
public static final TypedValue NULL = new TypedValue(null);
182
183
public TypedValue(Object value);
184
public TypedValue(Object value, TypeDescriptor typeDescriptor);
185
186
public Object getValue();
187
public TypeDescriptor getTypeDescriptor();
188
189
public boolean equals(Object other);
190
public int hashCode();
191
public String toString();
192
}
193
```
194
{ .api }
195
196
### EvaluationContext Interface
197
198
```java
199
public interface EvaluationContext {
200
// Root object access
201
TypedValue getRootObject();
202
203
// Accessor chains (default implementations return empty lists)
204
List<PropertyAccessor> getPropertyAccessors();
205
List<IndexAccessor> getIndexAccessors(); // since 6.2
206
List<ConstructorResolver> getConstructorResolvers();
207
List<MethodResolver> getMethodResolvers();
208
209
// Specialized resolvers
210
BeanResolver getBeanResolver();
211
TypeLocator getTypeLocator();
212
TypeConverter getTypeConverter();
213
TypeComparator getTypeComparator();
214
OperatorOverloader getOperatorOverloader();
215
216
// Variable management
217
void setVariable(String name, Object value);
218
Object lookupVariable(String name);
219
220
// Assignment support (default implementation)
221
TypedValue assignVariable(String name, Supplier<TypedValue> valueSupplier); // since 5.2.24
222
boolean isAssignmentEnabled(); // since 5.3.38
223
}
224
```
225
{ .api }
226
227
For detailed information about expression evaluation capabilities, see [Expression Evaluation](./expression-evaluation.md).
228
229
## SpEL Configuration
230
231
### SpelParserConfiguration
232
233
```java
234
public class SpelParserConfiguration {
235
public static final int DEFAULT_MAX_EXPRESSION_LENGTH = 10000;
236
public static final String SPRING_EXPRESSION_COMPILER_MODE_PROPERTY_NAME =
237
"spring.expression.compiler.mode";
238
239
public SpelParserConfiguration();
240
public SpelParserConfiguration(SpelCompilerMode compilerMode, ClassLoader compilerClassLoader);
241
public SpelParserConfiguration(boolean autoGrowNullReferences, boolean autoGrowCollections);
242
public SpelParserConfiguration(boolean autoGrowNullReferences, boolean autoGrowCollections,
243
int maximumAutoGrowSize);
244
public SpelParserConfiguration(SpelCompilerMode compilerMode, ClassLoader compilerClassLoader,
245
boolean autoGrowNullReferences, boolean autoGrowCollections,
246
int maximumAutoGrowSize);
247
public SpelParserConfiguration(SpelCompilerMode compilerMode, ClassLoader compilerClassLoader,
248
boolean autoGrowNullReferences, boolean autoGrowCollections,
249
int maximumAutoGrowSize, int maximumExpressionLength);
250
251
public SpelCompilerMode getCompilerMode();
252
public ClassLoader getCompilerClassLoader();
253
public boolean isAutoGrowNullReferences();
254
public boolean isAutoGrowCollections();
255
public int getMaximumAutoGrowSize();
256
public int getMaximumExpressionLength();
257
}
258
```
259
{ .api }
260
261
### SpelCompilerMode Enum
262
263
```java
264
public enum SpelCompilerMode {
265
OFF, // No compilation, interpreted mode only (default)
266
IMMEDIATE, // Compile immediately after first interpretation
267
MIXED // Switch between interpreted and compiled modes as needed
268
}
269
```
270
{ .api }
271
272
For comprehensive configuration details, see [SpEL Configuration](./spel-configuration.md).
273
274
## Evaluation Contexts
275
276
SpEL provides two main evaluation context implementations:
277
278
### SimpleEvaluationContext (Recommended for Data Binding)
279
280
```java
281
// Read-only data binding
282
SimpleEvaluationContext context = SimpleEvaluationContext
283
.forReadOnlyDataBinding()
284
.build();
285
286
// Read-write data binding with method access
287
SimpleEvaluationContext context = SimpleEvaluationContext
288
.forReadWriteDataBinding()
289
.withInstanceMethods()
290
.withArrayAccess()
291
.build();
292
```
293
{ .api }
294
295
### StandardEvaluationContext (Full-featured)
296
297
```java
298
StandardEvaluationContext context = new StandardEvaluationContext();
299
context.setRootObject(myObject);
300
context.setVariable("myVar", "Hello World");
301
context.registerFunction("reverse",
302
StringUtils.class.getDeclaredMethod("reverse", String.class));
303
```
304
{ .api }
305
306
For complete evaluation context documentation, see [Evaluation Contexts](./evaluation-contexts.md).
307
308
## Property and Index Access
309
310
SpEL supports flexible property and index access through configurable accessors:
311
312
### PropertyAccessor Interface
313
314
```java
315
public interface PropertyAccessor extends TargetedAccessor {
316
boolean canRead(EvaluationContext context, Object target, String name)
317
throws AccessException;
318
TypedValue read(EvaluationContext context, Object target, String name)
319
throws AccessException;
320
boolean canWrite(EvaluationContext context, Object target, String name)
321
throws AccessException;
322
void write(EvaluationContext context, Object target, String name, Object newValue)
323
throws AccessException;
324
}
325
```
326
{ .api }
327
328
### IndexAccessor Interface
329
330
```java
331
public interface IndexAccessor extends TargetedAccessor {
332
boolean canRead(EvaluationContext context, Object target, Object index)
333
throws AccessException;
334
TypedValue read(EvaluationContext context, Object target, Object index)
335
throws AccessException;
336
boolean canWrite(EvaluationContext context, Object target, Object index)
337
throws AccessException;
338
void write(EvaluationContext context, Object target, Object index, Object newValue)
339
throws AccessException;
340
}
341
```
342
{ .api }
343
344
For details on property and index access, see [Property and Index Access](./property-index-access.md).
345
346
## Method and Constructor Resolution
347
348
SpEL supports method invocation and object construction through resolvers:
349
350
### MethodResolver Interface
351
352
```java
353
@FunctionalInterface
354
public interface MethodResolver {
355
MethodExecutor resolve(EvaluationContext context, Object targetObject, String name,
356
List<TypeDescriptor> argumentTypes) throws AccessException;
357
}
358
```
359
{ .api }
360
361
### ConstructorResolver Interface
362
363
```java
364
public interface ConstructorResolver {
365
ConstructorExecutor resolve(EvaluationContext context, String typeName,
366
List<TypeDescriptor> argumentTypes) throws AccessException;
367
}
368
```
369
{ .api }
370
371
For method and constructor resolution details, see [Method and Constructor Resolution](./method-constructor-resolution.md).
372
373
## Type System Support
374
375
SpEL provides extensive type system support through various interfaces:
376
377
### TypeConverter Interface
378
379
```java
380
public interface TypeConverter {
381
boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);
382
Object convertValue(Object value, TypeDescriptor sourceType, TypeDescriptor targetType)
383
throws TypeConversionException;
384
}
385
```
386
{ .api }
387
388
### TypeLocator Interface
389
390
```java
391
public interface TypeLocator {
392
Class<?> findType(String typeName) throws EvaluationException;
393
}
394
```
395
{ .api }
396
397
For complete type system documentation, see [Type System Support](./type-system-support.md).
398
399
## Error Handling
400
401
SpEL provides a comprehensive exception hierarchy for error handling:
402
403
### ExpressionException (Base)
404
405
```java
406
public abstract class ExpressionException extends RuntimeException {
407
protected String expressionString;
408
protected int position = -1;
409
410
public String getExpressionString();
411
public int getPosition();
412
public String toDetailedString();
413
public String getSimpleMessage();
414
}
415
```
416
{ .api }
417
418
### Key Exception Types
419
420
- **ParseException**: Thrown during expression parsing
421
- **EvaluationException**: Thrown during expression evaluation
422
- **SpelEvaluationException**: SpEL-specific evaluation errors with message codes
423
- **SpelParseException**: SpEL-specific parsing errors
424
- **ExpressionInvocationTargetException**: Wraps exceptions from method/constructor invocation
425
426
For comprehensive error handling information, see [Error Handling](./error-handling.md).
427
428
## Advanced Features
429
430
### Expression Compilation
431
432
```java
433
SpelParserConfiguration config = new SpelParserConfiguration(
434
SpelCompilerMode.IMMEDIATE,
435
Thread.currentThread().getContextClassLoader()
436
);
437
SpelExpressionParser parser = new SpelExpressionParser(config);
438
439
SpelExpression expression = parser.parseRaw("name.toUpperCase()");
440
// Expression will be compiled to bytecode after first evaluation
441
```
442
{ .api }
443
444
### Custom Functions and Variables
445
446
```java
447
StandardEvaluationContext context = new StandardEvaluationContext();
448
context.setVariable("greeting", "Hello");
449
context.registerFunction("randomInt",
450
Math.class.getDeclaredMethod("random"));
451
452
Expression exp = parser.parseExpression("#greeting + ' ' + #randomInt() * 100");
453
```
454
{ .api }
455
456
### Bean References (in Spring Context)
457
458
```java
459
context.setBeanResolver(new BeanFactoryResolver(applicationContext));
460
Expression exp = parser.parseExpression("@myBean.someMethod()");
461
```
462
{ .api }
463
464
For detailed coverage of advanced features, see [Advanced Features](./advanced-features.md).
465
466
## Performance Considerations
467
468
- **Parser Reuse**: SpelExpressionParser is thread-safe and should be reused
469
- **Expression Caching**: Cache compiled expressions for repeated use
470
- **Compilation**: Use SpelCompilerMode.IMMEDIATE for frequently-evaluated expressions
471
- **Context Choice**: Use SimpleEvaluationContext for better performance in data-binding scenarios
472
- **Security**: SimpleEvaluationContext provides better security by restricting available features
473
474
## Thread Safety
475
476
- **SpelExpressionParser**: Thread-safe and reusable
477
- **SpelExpression**: Thread-safe for evaluation, not for configuration changes
478
- **StandardEvaluationContext**: Not thread-safe, should not be shared between threads
479
- **SimpleEvaluationContext**: Thread-safe when built with immutable configuration
480
481
## See Also
482
483
- [Expression Evaluation](./expression-evaluation.md) - Detailed expression evaluation capabilities
484
- [SpEL Configuration](./spel-configuration.md) - Parser and expression configuration options
485
- [Evaluation Contexts](./evaluation-contexts.md) - Context implementations and usage
486
- [Property and Index Access](./property-index-access.md) - Property and index access strategies
487
- [Method and Constructor Resolution](./method-constructor-resolution.md) - Method and constructor invocation
488
- [Type System Support](./type-system-support.md) - Type conversion and location services
489
- [Error Handling](./error-handling.md) - Exception handling and error reporting
490
- [Advanced Features](./advanced-features.md) - Compilation, functions, variables, and more