Spring Expression Language (SpEL) Example

By Arvind Rai, March 14, 2022
This page will walk through Spring Expression Language (SpEL) example.
1. The Spring Expression Language (SpEL) is a powerful expression language that supports querying and manipulating an object graph at runtime.
2. We can use SpEL with annotation configuration, XML configuration and SpelExpressionParser class.
3. In annotation-based and XML-based configuration, SpEL expression is used for defining BeanDefinition instances. In both cases, the syntax to define the expression is of the form #{ <expression string> } .

Using SpEL

Spring Expression Language is passed in #{ <expression string> } format in both cases, annotation configuration as well as XML configuration. In annotation configuration, we pass expression in @Value annotation.
1. The T operator is used to specify an instance of java.lang.Class.
@Value("#{ T(java.lang.Math).random() * 100}")
private Integer randomNumber; 
XML
The T operator is used to specify an instance of java.lang.Class.
<property name="randomNumber" value="#{ T(java.lang.Math).random() * 100}" /> 

2. Find the SpEL code to access values from property file.
@Configuration
@PropertySource("classpath:myproject.properties")
public class AppConfig {
    @Value("#{'${cp.user.age}'}")
    private Integer userAge;  
} 
myproject.properties
cp.user.age= 25 
XML
<util:properties id="userProp" location="classpath:myproject.properties" />
<bean id="user" class="com.concretepage.User">
      <property name="userAge" value="#{userProp['cp.user.age']}" />
</bean> 
3. Find the SpEL code to access values from another bean.
@Value("#{address.country}")
private String userCountry;
 
@Bean("address")
public Address address() {
   return new Address("India", 251586);
} 
XML
<bean id="user" class="com.concretepage.User">
	<property name="userCountry" value="#{address.country}" />
</bean>
<bean id="address" class="com.concretepage.Address">
	<property name="country" value="India" />
	<property name="pin" value="251586" />        
</bean> 
4. Using systemProperties.
@Value("#{systemProperties['java.home']}") 
private String mySystemVal; 
XML
<property name="mySystemVal" value="#{systemProperties['java.home']}" /> 
5. Passing a String.
@Value("#{'India'}")
private String userCountry; 
XML
<property name="userCountry" value="#{'India'}" /> 
6. Passing integer value.
@Value("#{15 * 10}")
private Integer myNum; 
XML
<property name="myNum" value="#{15 * 10}" /> 
6. Passing boolean value.
@Value("#{true}")
private Boolean userActive; 
XML
<property name="userActive" value="#{true}" /> 
7. Passing null.
@Value("#{null}")
private String userCountry; 
XML
<property name="userCountry" value="#{null}" /> 
8. With List.
@Value("#{'Java,HTML,Spring'.split(',')}")
private List<String> userSkills; 
XML
<property name="userSkills" value="#{'Java,HTML,Spring'.split(',')}" /> 
9. With Map.
@Value("#{{101:'Mahesh',102:'Surya'}}")
private Map<Integer, String> teamMates; 
XML
<property name="teamMates" value="#{{101:'Mahesh',102:'Surya'}}" /> 

Operators

The SpEL supports relational operators, logical operators, mathematical operators and assignment operators.

1. Relational Operators
The SpEL supports the relational operators that are lt (<) , gt (>) , le (<=) , ge (>=) , eq (==) , ne (!=) , not (!) , div (/) , mod (%) .
Find the examples of some of them.
a. lt (<)
@Value("#{(10 < 15)}")
private Boolean myVal; // true 
b. gt (>)
@Value("#{(30 > 15)}")
private Boolean myVal; // true 
c. not (!)
@Value("#{!(12 <= 18)}") // false
private Boolean myVal; 
d. eq (==)
@Value("#{address.country == 'India'}")
private Boolean myVal; 

2. Logical Operators
The SpEL supports following logical operators.
a. and (&&)
@Value("#{10 > 6 && 15 < 20}") 
private Boolean isUserActive; // true 
b. or (||)
@Value("#{10 > 15 || 15 < 20}")
private Boolean isUserActive; // true 
c. not (!)
@Value("#{!(10 > 15)}")
private Boolean isUserActive; //false 

3. Mathematical Operators
On numbers, we can use mathematical operators such as +, -, *, /, %, ^ . The + can also be used with string.
Find some of examples.
a.
@Value("#{15 + 10}")
private Integer myVal; // 25 
b.
@Value("#{150 - 100}")
private Integer myVal; // 50 
c.
@Value("#{15 * 10}")
private Integer myVal; // 150 
d.
@Value("#{45 / 9}")
private Integer myVal; // 5 

4. Ternary Operator (If-Then-Else)
We can use ternary operator for performing if-then-else conditional logic inside the expression.
@Value("#{user.role == 'Admin'? true : false}")
private Boolean permission; 

5. Safe Navigation Operator
The safe navigation operator (?) is used to avoid a NullPointerException.
@Value("#{address?.country}")
private String userCountry; 

Collection Selection

SpEL performs collection selection that means we can transform a source collection into another collection by selecting from its entries. For collection selection, syntax is .?[selectionExpression] . Find the examples.
a. With List
@Value("#{allUsers.?[userCountry == 'India']}")
private List<User> usersFromIndia;

@Bean("allUsers")
public List<User> allUsers() {
   return Arrays.asList(
		 new User("Anisha", "India"),
		 new User("Alina", "Russia"),
		 new User("Radha", "India")
	   );
 } 
Now check the list.
usersFromIndia.forEach(u -> System.out.println(u.getUserName() + ", " + u.getUserCountry())); 
Output
Anisha, India
Radha, India 
b. With Map
@Value("#{allStudents.?[value<24]}")
private Map<String, Integer> students;

@Bean("allStudents")
public Map<String, Integer> allStudents() {
   Map<String, Integer> map = new HashMap<>();
   map.put("Ram", 21);
   map.put("Shyam", 37);
   map.put("Mohan", 23);
   return map;
} 
Print the students .
System.out.println(students); 
Output
{Mohan=23, Ram=21} 
We can also select only first and last element matching the selection. To obtain the first matching selection, the syntax is .^[selectionExpression] . To obtain the last matching selection, the syntax is .$[selectionExpression] .

Collection Projection

Collection projection evaluates the sub-expression and the result is a new collection. The syntax for projection is .![projectionExpression] .
Suppose we have a class as following.
public class User {
   private String userName;
   private String userCountry;
   ------
} 
Find the code to use collection projection.
@Value("#{allUsers.![userCountry]}")
private List<String> countries;	
 
@Bean("allUsers")
public List<User> allUsers() {
   return Arrays.asList(
		 new User("Anisha", "India"),
		 new User("Alina", "Russia"),
		 new User("Radha", "Nepal")
	   );
} 
Print the countries .
System.out.println(countries); 
Output
[India, Russia, Nepal] 

Using SpelExpressionParser

The SpEL provides SpelExpressionParser class for parsing expression standalone.
1. Parsing String and numerical values.
ExpressionParser parser = new SpelExpressionParser();
//Parsing String
Expression exp1 = parser.parseExpression("'This is SpEL'"); 
String msg = (String) exp1.getValue();
System.out.println(msg); // This is SpEL

//Parsing Integer
Expression exp2 = parser.parseExpression("215 * 5"); 
Integer intVal = (Integer) exp2.getValue();
System.out.println(intVal); // 1075

//Invoking methods on string literal
Expression exp3 = parser.parseExpression("'Welcome to you'.length()"); 
Integer len = (Integer) exp3.getValue();
System.out.println(len); // 14 
2. SpEL can parse an expression string against a specific object instance.
Suppose we have a class as following.
public class User {
   private String userName;
   private String userCountry;
   ------
} 
Find the object of User class.
User user = new User("Alina", "Russia"); 
We will parse userCountry and will get its value.
ExpressionParser parser = new SpelExpressionParser();
Expression exp = parser.parseExpression("userCountry");
String country = (String) exp.getValue(user);
System.out.println(country); // Russia 

Reference

Spring Expression Language (SpEL)

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI







©2024 concretepage.com | Privacy Policy | Contact Us