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'}}" /> 


@Value("#{150 - 100}")
private Integer myVal; // 50 

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 

Example :- 


LearnSpel.java // class





package springExpressionLanguageSpel;


import java.util.List;

import java.util.Map;


import org.springframework.beans.factory.annotation.Value;

import org.springframework.stereotype.Component;


@Component("spel") // create bean

public class LearnSpel {

@Value("#{22}")

private Integer userAge;

@Value("#{'India'}")

private String userCountry;

@Value("#{22+55}")

private Integer myNum;

@Value("#{22>55}")

private Boolean userActive;

@Value("#{l}")

private List<String> userSkills;

@Value("#{{101:'Mahesh',102:'Surya'}}")

private Map<Integer, String> teamMates;

@Value("#{(10 < 15)}")

private Boolean myVal1; // true

@Value("#{(30 > 15)}")

private Boolean myVal2; // true

@Value("#{!(12 <= 18)}")

private Boolean myVal3;

@Value("#{10 > 6 && 15 < 20}")

private Boolean isUserActive;

@Value("#{10 > 15 || 15 < 20}")

private Boolean isUserActive1;

@Value("#{!(10 > 15)}")

private Boolean isUserActive2;

@Value("#{15 + 10}")

private Integer myVal7;

@Value("#{150 - 100}")

private Integer myVal5;

@Value("#{45 / 9}")

private Integer myVal6;

@Value("#{ T(java.lang.Math).random() * 100}") // The T operator is used to specify an instance of java.lang.Class.

private Integer randomNumber;


@Override

public String toString() {

return "LearnSpel [userAge=" + userAge + ", userCountry=" + userCountry + ", myNum=" + myNum + ", userActive="

+ userActive + ", userSkills=" + userSkills + ", teamMates=" + teamMates + ", myVal1=" + myVal1

+ ", myVal2=" + myVal2 + ", myVal3=" + myVal3 + ", isUserActive=" + isUserActive + ", isUserActive1="

+ isUserActive1 + ", isUserActive2=" + isUserActive2 + ", myVal7=" + myVal7 + ", myVal5=" + myVal5

+ ", myVal6=" + myVal6 + ", randomNumber=" + randomNumber + ", getClass()=" + getClass()

+ ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";

}


}



..........spelConfig.xml


<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:util="http://www.springframework.org/schema/util"

xsi:schemaLocation="http://www.springframework.org/schema/beans

https://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context.xsd

http://www.springframework.org/schema/util

http://www.springframework.org/schema/util/spring-util.xsd">

<context:component-scan base-package="springExpressionLanguageSpel" />

<util:list list-class="java.util.Vector" id="l">

<value>c</value>

<value>c++</value>

<value>java</value>

<value>Python</value>

</util:list>

</beans>







....Test.java



package springExpressionLanguageSpel; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext context =new ClassPathXmlApplicationContext("springExpressionLanguageSpel/spelConfig.xml"); LearnSpel obj1= (LearnSpel)context.getBean("spel"); System.out.println(obj1); } }






Output:-


LearnSpel [userAge=22, userCountry=India, myNum=77, userActive=false, userSkills=[c, c++, java, Python], teamMates={101=Mahesh, 102=Surya}, myVal1=true, myVal2=true, myVal3=false, isUserActive=true, isUserActive1=true, isUserActive2=true, myVal7=25, myVal5=50, myVal6=5, randomNumber=61, getClass()=class springExpressionLanguageSpel.LearnSpel, hashCode()=1176968662, toString()=springExpressionLanguageSpel.LearnSpel@46271dd6]



Comments

Popular posts from this blog

Two Sum II - Input Array Is Sorted

Comparable Vs. Comparator in Java

Increasing Triplet Subsequence