diff --git a/spring-framework-reference/src/expressions.xml b/spring-framework-reference/src/expressions.xml
index 644030f0934..2a537a68d11 100644
--- a/spring-framework-reference/src/expressions.xml
+++ b/spring-framework-reference/src/expressions.xml
@@ -19,26 +19,26 @@
projects in the Spring portfolio, including tooling requirements for code
completion support within the eclipse based SpringSource Tool Suite. That
said, SpEL is based on an technology agnostic API allowing other
- expression language implementations to be integreatd should the need
+ expression language implementations to be integreated should the need
arise.
While SpEL serves as the foundation for expression evaluation within
the Spring portfolio, it is not directly tied to Spring and can be used
- independently. In order to be self contained many of the examples shown
- use SpEL as if it was an independent expression language. This requires
- creating a few boostrapping infrastructure classes such as the parser.
- Most Spring users will not need to deal with this infrastructure and will
- instead only be authoring expression strings for evaluation. An example of
- this typical use is the integration of SpEL into the definition of XML or
- annotated based bean definitions shown in the section Expression support for defining bean
definitions.
- This chapter covers the features of the expression language and its
- synax. In several places an Inventor and Inventor's Society class are used
- as the target objects for expression evaluation. These class declarations
- and the data used to populate them are listed at the end of the chapter.
-
+ This chapter covers the features of the expression language, its
+ API, and its language sytnax. In several places an Inventor and Inventor's
+ Society class are used as the target objects for expression evaluation.
+ These class declarations and the data used to populate them are listed at
+ the end of the chapter.
@@ -100,7 +100,7 @@
Expression Evaluation using Spring's Expression Interface
- This section introduces simple use of SpEL interfaces and its
+ This section introduces the simple use of SpEL interfaces and its
expression language. The complete language reference can be found in the
section Language
Reference
@@ -108,16 +108,21 @@
The following code introduces the SpEL API to evaluate the literal
string expression 'Hello World'
- ExpressionParser parser = new SpelAntlrExpressionParser();
+ ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("'Hello World'");
String message = (String) exp.getValue();The value of the
message variable is simply 'Hello World'.
+ The SpEL classes and interfaces you are most likely to use are
+ located in the packages org.springframework.expression
+ and its subpackages spel.antlr and
+ spel.support.
+
The expression language is based on a grammar and uses ANTLR to
construct the lexer and parser. The interface
ExpressionParser is responsible for parsing
- an expression string, in this case a string literal denoted by the
- surrounding single quotes. The interface
+ an expression string. In this example the expression string is a string
+ literal denoted by the surrounding single quotes. The interface
Expression is responsible for evaluating
the previously defined expression string. There are two exceptions that
can be thrown, ParseException and
@@ -128,10 +133,10 @@ String message = (String) exp.getValue();The value of the
SpEL supports a wide range of features, such a calling methods,
accessing properties and calling constructors.
- As an example to method invocation, we call the 'concat' method on
+ As an example of method invocation, we call the 'concat' method on
the string literal
- ExpressionParser parser = new SpelAntlrExpressionParser();
+ ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.concat(!)");
String message = (String) exp.getValue();
@@ -140,24 +145,24 @@ String message = (String) exp.getValue();As an example of calling a JavaBean property, the String property
'Bytes' can be called as shown below
- ExpressionParser parser = new SpelAntlrExpressionParser();
+ ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.bytes"); // invokes 'getBytes()'
byte[] bytes = (byte[]) exp.getValue();Upper or lowercase can be used to specify the property name. SpEL
also supports nested properties using standard 'dot' notation, i.e.
- prop1.prop2.prop3.
+ prop1.prop2.prop3 and the setting of property valuesPublic fields may also be accessed
- ExpressionParser parser = new SpelAntlrExpressionParser();
+ ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("'Hello World'.bytes.length"); // invokes 'getBytes().length'
int length = (Integer) exp.getValue();
- The String's constructor can be called instead of using the string
+ The String's constructor can be called instead of using a string
literal
- ExpressionParser parser = new SpelAntlrExpressionParser();
+ ExpressionParser parser = new SpelAntlrExpressionParser();
Expression exp = parser.parseExpression("new String('hello world').toUpperCase()");
String message = exp.getValue(String.class);
@@ -173,47 +178,60 @@ String message = exp.getValue(String.class);
we retrieve the Name property from an instance of the
Inventor class.
- GregorianCalendar c = new GregorianCalendar();
+ // Create and set a calendar
+GregorianCalendar c = new GregorianCalendar();
c.set(1856, 7, 9);
// The constructor arguments are name, birthday, and nationaltiy.
Inventor tesla = new Inventor("Nikola Tesla", c.getTime(), "Serbian");
ExpressionParser parser = new SpelAntlrExpressionParser();
-Expression exp = parser.parseExpression("Name");
+Expression exp = parser.parseExpression("name");
EvaluationContext context = new StandardEvaluationContext();
context.setRootObject(tesla);
String name = (String) exp.getValue(context);In the last
line, the value of the string variable 'name' will be set to "Nikola
- Tesla".
+ Tesla". The class StandardEvaluationContext is where you can specify which
+ object the "Name" property will be evaluated against. You can reuse the
+ same expression over and over again and set a new root object on the
+ evaluation context. Expressions are evaluated using reflection. In standalone usage of SpEL you will need to create the parser
as well as provide an evaluation context. However, more common usage
- would be to provide only the SpEL expression string as part of a
- configuration file, for example for Spring bean or web flow
- definitions. The parser, evaluation context and root object will be
- set up for you implicitly.
-
+ is to provide only the SpEL expression string as part of a
+ configuration file, for example for Spring bean or Spring Web Flow
+ definitions. In this case, the parser, evaluation context, root object
+ and any predefined variables will be set up for you implicitly.
+ As a final introductory example, the use of a boolean operator is
+ shown using the Inventor object in the previous example
+
+ Expression exp = parser.parseExpression("name == 'Nikola Tesla'");
+boolean isEqual = exp.getValue(context, Boolean.class); // evaluates to trueThe EvaluationContext interface The interface EvaluationContext is
used when evaluating an expression to resolve properties, methods
- ,fields, and help perform type conversion. The out-of-the-box
+ ,fields, and to help perform type conversion. The out-of-the-box
implementation, StandardEvaluationContext ,uses
- reflection to manipulate the object, caching java.lang.reflect Method,
- Fields, and Constructor instances for increased performance.
+ reflection to manipulate the object, caching
+ java.lang.reflect's Method,
+ Field, and Constructor
+ instances for increased performance.
The StandardEvaluationContext is where you
specify the root object to evaluate against via the method
setRootObject . You can also specify variables
- and functions using the methods setVariable
- and, registerFunction. The use of variables and
- functions are described in the language reference section.
+ and functions that will be used in the expression using the methods
+ setVariable and
+ registerFunction. The use of variables and
+ functions are described in the language reference sections Variables and Functions.
Type Conversion
@@ -243,7 +261,7 @@ String name = (String) exp.getValue(context);In the last
A property or constructor-arg value can be set using expressions
as shown below
- <bean id="numberGuess" class="org.spring.samples.NumberGuess">
+ <bean id="numberGuess" class="org.spring.samples.NumberGuess">
<property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>
<!-- other properties -->
@@ -252,7 +270,7 @@ String name = (String) exp.getValue(context);In the last
The variable 'systemProperties' is predefined, so you can use it
in your expressions as shown below.
- <bean id="taxCalculator" class="org.spring.samples.TaxCalculator">
+ <bean id="taxCalculator" class="org.spring.samples.TaxCalculator">
<property name="defaultLocale" value="#{ systemProperties['user.region'] }"/>
<!-- other properties -->
@@ -261,7 +279,7 @@ String name = (String) exp.getValue(context);In the last
You can also refer to other bean properties by name, for
example
- <bean id="numberGuess" class="org.spring.samples.NumberGuess">
+ <bean id="numberGuess" class="org.spring.samples.NumberGuess">
<property name="randomNumber" value="#{ T(java.lang.Math).random() * 100.0 }"/>
<!-- other properties -->
@@ -278,13 +296,14 @@ String name = (String) exp.getValue(context);In the last
Annotation-based configuration
- The @Value annotation can be placed on fields, methods and
- method/constructor parameters to specify a default value.
+ The @Value annotation can be placed on fields,
+ methods and method/constructor parameters to specify a default
+ value.Here is an example to set the default value of a field
variable
- public static class FieldValueTestBean
+ public static class FieldValueTestBean
@Value("#{ systemProperties['user.region'] }")
private String defaultLocale;
@@ -306,7 +325,7 @@ String name = (String) exp.getValue(context);In the last
The equivalent but on a property setter method is shown
below
- public static class PropertyValueTestBean
+ public static class PropertyValueTestBean
private String defaultLocale;
@@ -326,7 +345,7 @@ String name = (String) exp.getValue(context);In the last
Autowired methods and constructors can also use the
@Value annotation.
- public class SimpleMovieLister {
+ public class SimpleMovieLister {
private MovieFinder movieFinder;
private String defaultLocale;
@@ -341,7 +360,7 @@ String name = (String) exp.getValue(context);In the last
// ...
}
- public class MovieRecommender {
+ public class MovieRecommender {
private String defaultLocale;
@@ -362,18 +381,55 @@ String name = (String) exp.getValue(context);In the last
Language Reference
-
-
-
+ Literal expressions
- blah blah
+ The types of literal expressions supported are strings, dates,
+ numeric values (int, real, and hex), boolean and null. String are
+ delimited by single quotes. To put a single quote itself in a string use
+ the backslash character. The following listing shows simple usage of
+ literals. Typically they would not be used in isolation like this, but
+ as part of a more complex expression, for example using a literal on one
+ side of a logical comparison operator.
+
+ ExpressionParser parser = new SpelAntlrExpressionParser();
+
+String helloWorld = (String) parser.parseExpression("'Hello World'").getValue(); // evals to "Hello World"
+
+double avogadrosNumber = (Double) parser.parseExpression("6.0221415E+23").getValue();
+
+int maxValue = (Integer) parser.parseExpression("0x7FFFFFFF").getValue(); // evals to 2147483647
+
+boolean trueValue = (Boolean) parser.parseExpression("true").getValue();
+
+Object nullValue = parser.parseExpression("null").getValue();
+
+
+ Numbers support the use of the negative sign, exponential
+ notation, and decimal points. By default real numbers are parsed using
+ Double.parseDouble().Properties, Arrays, Lists, Dictionaries, Indexers
- blah blah
+ Navigating through properties is easy, just use a period to
+ indicate a nested property value. The instances of Inventor class, pupin
+ and tesla, were populated with data listed in section Section Classes used in the
+ examples. To navigate "down" and get Tesla's year of birth and
+ Pupin's city of birth the following expressions are used
+
+ int year = (Integer) parser.parseExpression("Birthdate.Year + 1900").getValue(context); // 1856
+
+
+String city = (String) parser.parseExpression("placeOfBirth.City").getValue(context);
+
+ Case insensitivty is allowed for the first letter of proprety
+ names. The contents of arrays and lists are obtained using square
+ bracket notation.
+
+
@@ -432,7 +488,7 @@ String name = (String) exp.getValue(context);In the last
blah blah
-
+ Variablesblah blah
@@ -444,7 +500,7 @@ String name = (String) exp.getValue(context);In the last
-
+ Functionsblah blah
@@ -457,7 +513,7 @@ String name = (String) exp.getValue(context);In the last
-
+ Classes used in the examples