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.propertiesXML<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()));
OutputAnisha, 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);
OutputWe 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);
OutputUsing 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 :-
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
Post a Comment