Expression languages are generally used for simple scripting to manipulate object graphs in a non object-oriented context. For example, if we want to read data or call a method of a Java object from a JSP, XML, or XHTML page, JSP EL and Unified Expression Language (UEL) come to the rescue. These expression languages allow page authors to access external data objects in a simple and easy-to-use way, compatible with tag-based languages such as XML and HTML.
The Spring Expression Language (SpEL), with a language syntax similar to UEL, is a powerful expression language built for querying and manipulating an object graph at runtime. It offers additional features, most notably method invocation and basic string-templating functionality.
SpEL can be used inside a wide variety of technologies that come under the Spring family of projects as well as many technologies that integrate with Spring. It can be used directly in the Spring configuration metadata files, both in XML as well as Java annotations in the form #{expression-string}
. You can use SpEL inside many view technologies, such as JSP, XML, and XHTML, when integrated with the corresponding technologies, such as JSF, JSP, and Thymeleaf.
The SpEL expression language supports the following functionalities out of the box:
SpEL can be used to specify default values for fields, methods and method or constructor arguments using the @Value
annotation. The following sample listing contains some excellent usage of SpEL expressions at the field level:
@Component @Scope("prototype") public class TaskSnapShot { Value("#{taskService.findAllTasks().size()}") private String totalTasks; @Value("#{taskService.findAllTasks()}") private List<Task> taskList; @Value("#{ new java.util.Date()}") private Date reportTime; @Value("#{taskService.findAllTasks().?[status == 'Open']}") private List<Task> openTasks; ... }
The same approach can be used for XML bean definitions too.
Generally, most users use SpEL to evaluate expressions embedded in XML, XHTML, or annotations. While SpEL serves as the foundation for expression evaluation within the Spring portfolio, it can be used independently in non-Spring environments using the SpEL API. The SpEL API provides the bootstrapping infrastructure to use SpEL programmatically in any environment.
The SpEL API classes and interfaces are located in the (sub)packages under org.springframework.expression
. They provide the specification and default SpEL implementations which can be used directly or extended.
The following interfaces and classes form the foundation of the SpEL API:
Class/Interface |
Description |
---|---|
|
The specification for an expression capable of evaluating itself against context objects independent of any language such as OGNL or UEL. It encapsulates the details of a previously parsed expression string. |
|
A SpEL-compliant, parsed expression that is ready to be evaluated standalone or in a specified context. |
|
Parses expression strings (templates as well as standard expression strings) into compiled expressions that can be evaluated. |
|
SpEL parser. Instances are reusable and thread-safe. |
|
Expressions are executed in an evaluation context, where references are resolved when encountered during expression evaluation. |
|
The default |
|
Compiles a regular parsed expression instead of the interpreted form to a class containing bytecode for evaluation. A far faster method, but still at an early stage, it does not yet support every kind of expression as of Spring 4.1. |
Let's take a look at an example that evaluates an expression using the SpEL API:
@Component public class TaskSnapshotBuilder { @Autowired private TaskService taskService; public TaskSnapShot buildTaskSnapShot() { TaskSnapShot snapshot = new TaskSnapShot(); ExpressionParser parser = new SpelExpressionParser(); EvaluationContext context = new StandardEvaluationContext(taskService); Expression exp = parser.parseExpression("findAllTasks().size()"); snapshot.setTotalTasks(exp.getValue(context).toString()); exp = parser.parseExpression("findAllTasks()"); snapshot.setTaskList((List<Task>)exp.getValue(context)); exp = parser.parseExpression("new java.util.Date()"); snapshot.setReportTime((Date)exp.getValue(context)); exp = parser.parseExpression("findAllTasks().?[status == 'Open']"); snapshot.setOpenTasks((List<Task>)exp.getValue(context)); return snapshot; } }
In normal scenarios, you would not need to directly use the SpEL API in a Spring application; SpEL with annotation or XML bean definitions would be better candidates. The SpEL API is mostly used to load externalized business rules dynamically at runtime.