SpEl

Spring Expression Language Example

The Spring Expression Language (SpEL for short) is a powerful expression language that supports querying and manipulating an object graph at runtime. SpEL expressions can be used with XML or annotation based configuration metadata for defining BeanDefinitions. In both cases the syntax to define the expression is of the form #{ <expression string> }.

We can use SpEL to inject a bean or a bean property in another bean, or even to invoke a bean method in another bean. SpEL also supports most of the standard mathematical, logical or relational operators, as also the ternary operator (if-then-else) to perform conditional checking. We can also get the elements of a Map or a List using SpEL just like we do in Java. Regular expressions are also supported in SpEL using the matches operator. In addition, Spring provides its own API for evaluating expressions.

In this example we will demonstrate how to use SpEL with XML and annotation based configuration to implement all the cases mentioned above. We will also show how to use the ExpressionParser interface provided by Spring API for parsing an expression string.

Our preferred development environment is Eclipse. We are using Eclipse Juno (4.2) version, along with Maven Integration plugin version 3.1.0. You can download Eclipse from here and Maven Plugin for Eclipse from here. The installation of Maven plugin for Eclipse is out of the scope of this tutorial and will not be discussed. We are also using Spring version 3.2.3 and the JDK 7_u_21.

Let’s begin.

1. Create a new Maven project

Go to File -> Project ->Maven -> Maven Project.

New-Maven-Project

In the “Select project name and location” page of the wizard, make sure that “Create a simple project (skip archetype selection)” option is checked, hit “Next” to continue with default values.

Maven-Project-Name-Location

In the “Enter an artifact id” page of the wizard, you can define the name and main package of your project. We will set the “Group Id” variable to "com.javacodegeeks.snippets.enterprise" and the “Artifact Id” variable to "springexample". The aforementioned selections compose the main project package as "com.javacodegeeks.snippets.enterprise.springexample" and the project name as "springexample". Hit “Finish” to exit the wizard and to create your project.

Configure-Maven-Project

The Maven project structure is shown below:

Maven-project-structure

    It consists of the following folders:

  • /src/main/java folder, that contains source files for the dynamic content of the application,
  • /src/test/java folder contains all source files for unit tests,
  • /src/main/resources folder contains configurations files,
  • /target folder contains the compiled and packaged deliverables,
  • the pom.xml is the project object model (POM) file. The single file that contains all project related configuration.

2. Add Spring 3.2.3 dependency

  • Locate the “Properties” section at the “Overview” page of the POM editor and perform the following changes:
    Create a new property with name org.springframework.version and value 3.2.3.RELEASE.
  • Navigate to the “Dependencies” page of the POM editor and create the following dependencies (you should fill the “GroupId”, “Artifact Id” and “Version” fields of the “Dependency Details” section at that page):
    Group Id : org.springframework Artifact Id : spring-web Version : ${org.springframework.version}

Alternatively, you can add the Spring dependencies in Maven’s pom.xml file, by directly editing it at the “Pom.xml” page of the POM editor, as shown below:
 
pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.javacodegeeks.snippets.enterprise</groupId>
	<artifactId>springexample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
	</dependencies>

	<properties>
		<spring.version>3.2.3.RELEASE</spring.version>
	</properties>
</project>

As you can see Maven manages library dependencies declaratively. A local repository is created (by default under {user_home}/.m2 folder) and all required libraries are downloaded and placed there from public repositories. Furthermore intra – library dependencies are automatically resolved and manipulated.

Note that there is no need for extra dependency in order to include the Spring EL in the pom.xml, since it is included in Spring core.

3. A simple bean reference example with Spring EL

Let’s start with injecting a bean in another bean using SpEL. Book.java class is a bean with two properties. We will inject the bookBean and one of its properties to another bean that belongs to Author.java class. The two classes are presented below:

Book.java

package com.javacodegeeks.snippets.enterprise;


public class Book {

	private long id;
	
	private String title;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	} 

	@Override
	public String toString(){
		return title;
	}
}

Author.java

package com.javacodegeeks.snippets.enterprise;


public class Author {
	
	private String name;
	
	private Book book;
	
	private String bookTitle;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public Book getBook() {
		return book;
	}

	public void setBook(Book book) {
		this.book = book;
	}

	public String getBookTitle() {
		return bookTitle;
	}

	public void setBookTitle(String bookTitle) {
		this.bookTitle = bookTitle;
	}
	
	@Override
	public String toString(){
		return name + " has writen the book : " + book + ". \n" + bookTitle + " is a wonderful title of a wonderful book.";
	}
}

3.1 XML-based configuration

The beans are defined in applicationContext.xml file. The #{bookBean} expression is used to inject bookBean into book property of authorBean, whereas the #{bookBean.title} is used to inject title property of bookBean into bookTitle property of authorBean.

applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

	<bean id="bookBean" class="com.javacodegeeks.snippets.enterprise.Book">
		<property name="id" value="12345" />
		<property name="title" value="Le Petit Prince (The Little Prince)" />
	</bean>
 
	<bean id="authorBean" class="com.javacodegeeks.snippets.enterprise.Author">
		<property name="name" value="Antoine de Saint-Exupéry" />
		<property name="book" value="#{bookBean}" />
		<property name="bookTitle" value="#{bookBean.title}" />
	</bean>
	
</beans>

3.2 Annotation-based configuration

The same expressions will be used in annotations. The @Component annotation is used to register the component in Spring and the @Value annotation is used to set the values into beans properties. The two classes with the annotations are presented below:

Book.java

package com.javacodegeeks.snippets.enterprise;

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

@Component("bookBean")
public class Book {

	@Value("12345")
	private long id;
	
	@Value("Le Petit Prince (The Little Prince)")
	private String title;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	} 
	
	@Override
	public String toString(){
		return title;
	}
}

Author.java

package com.javacodegeeks.snippets.enterprise;

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


@Component("authorBean")
public class Author {
	
	@Value("Antoine de Saint-Exupéry")
	private String name;
	
	@Value("#{bookBean}")
	private Book book;
	
	@Value("#{bookBean.title}")
	private String bookTitle;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public Book getBook() {
		return book;
	}

	public void setBook(Book book) {
		this.book = book;
	}

	public String getBookTitle() {
		return bookTitle;
	}

	public void setBookTitle(String bookTitle) {
		this.bookTitle = bookTitle;
	}
	
	@Override
	public String toString(){
		return name + " has writen the book : " + book + ". \n" + bookTitle + " is a wonderful title of a wonderful book.";
	}	
}

The only thing needed in applicationContext.xml is to enable auto component-scan, as shown below:

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

	<context:component-scan base-package="com.javacodegeeks.snippets.enterprise" />
	
</beans>

3.3 Run the application

We can run this application, in both xml and annotation based configuration, using the App.java class.

App.java

package com.javacodegeeks.snippets.enterprise;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

	public static void main(String[] args) {
	
			ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
			Author author = (Author) context.getBean("authorBean");
			System.out.println(author.toString());
			context.close();
	}
}

The output is the one presented below:

Antoine de Saint-Exupéry has writen the book : Le Petit Prince (The Little Prince). 
Le Petit Prince (The Little Prince) is a wonderful title of a wonderful book.

 

4. Method invocation with Spring EL

Now, we will use Expression Language to execute a method in bookBean and inject the result in authorBean. We are adding a method, String getBookInfo(String authorName) in Book.java class and a new property, fullAuthorInfo in Author.java class, as shown below:

Book.java

package com.javacodegeeks.snippets.enterprise;


public class Book {

	private long id;
	
	private String title;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	} 
	
	public String getBookInfo(String authorName){
		return authorName + " has writen the book " + title + ", with book id " + ""+ id + ".";
	}

	@Override
	public String toString(){
		return title;
	}
}

Author.java

package com.javacodegeeks.snippets.enterprise;


public class Author {
	
	private String name;
	
	private Book book;
	
	private String bookTitle;
	
	private String fullAuthorInfo;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public Book getBook() {
		return book;
	}

	public void setBook(Book book) {
		this.book = book;
	}

	public String getBookTitle() {
		return bookTitle;
	}

	public void setBookTitle(String bookTitle) {
		this.bookTitle = bookTitle;
	}
	
	public String getFullAuthorInfo() {
		return fullAuthorInfo;
	}

	public void setFullAuthorInfo(String fullAuthorInfo) {
		this.fullAuthorInfo = fullAuthorInfo;
	}
	
	@Override
	public String toString(){
		return name + " has writen the book : " + book + ". \n" + bookTitle + " is a wonderful title of a wonderful book.";
	}
}

4.1 XML-based configuration

Let’s define the new property in applicationContext.xml file.

applicationContext.xml:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

	<bean id="bookBean" class="com.javacodegeeks.snippets.enterprise.Book">
		<property name="id" value="12345" />
		<property name="title" value="Le Petit Prince (The Little Prince)" />
	</bean>
 
	<bean id="authorBean" class="com.javacodegeeks.snippets.enterprise.Author">
		<property name="name" value="Antoine de Saint-Exupéry" />
		<property name="book" value="#{bookBean}" />
		<property name="bookTitle" value="#{bookBean.title}" />
		<property name="fullAuthorInfo" value="#{bookBean.getBookInfo('Antoine de Saint-Exupéry')}" />
	</bean>
	
</beans>

4.2 Annotation-based configuration

The same steps are followed using annotations:

Book.java

package com.javacodegeeks.snippets.enterprise;

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

@Component("bookBean")
public class Book {

	@Value("12345")
	private long id;
	
	@Value("Le Petit Prince (The Little Prince)")
	private String title;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	} 
	
	public String getBookInfo(String authorName){
		return authorName + " has writen the book " + title + ", with book id " + ""+ id + ".";
	}

	@Override
	public String toString(){
		return title;
	}
}

Author.java

package com.javacodegeeks.snippets.enterprise;

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


@Component("authorBean")
public class Author {
	
	@Value("Antoine de Saint-Exupéry")
	private String name;
	
	@Value("#{bookBean}")
	private Book book;
	
	@Value("#{bookBean.title}")
	private String bookTitle;

	@Value("#{bookBean.getBookInfo('Antoine de Saint-Exupéry')}")
	private String fullAuthorInfo;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public Book getBook() {
		return book;
	}

	public void setBook(Book book) {
		this.book = book;
	}

	public String getBookTitle() {
		return bookTitle;
	}

	public void setBookTitle(String bookTitle) {
		this.bookTitle = bookTitle;
	}
	
	public String getFullAuthorInfo() {
		return fullAuthorInfo;
	}

	public void setFullAuthorInfo(String fullAuthorInfo) {
		this.fullAuthorInfo = fullAuthorInfo;
	}
	
	@Override
	public String toString(){
		return name + " has writen the book : " + book + ". \n" + bookTitle + " is a wonderful title of a wonderful book.";
	}	
}

In this case applicationContext.xml file is the same as the one in the previous annotation-based configuration.

applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

	<context:component-scan base-package="com.javacodegeeks.snippets.enterprise" />
	
</beans>

4.3 Run the application

Using the same App.java class as in 3.3, we are getting the output below:

App.java

package com.javacodegeeks.snippets.enterprise;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {

	public static void main(String[] args) {
	
			ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
			Author author = (Author) context.getBean("authorBean");
			System.out.println(author.toString());
			System.out.println(author.getFullAuthorInfo());
			context.close();
	}
}
Antoine de Saint-Exupéry has writen the book : Le Petit Prince (The Little Prince). 
Le Petit Prince (The Little Prince) is a wonderful title of a wonderful book.
Antoine de Saint-Exupéry has writen the book Le Petit Prince (The Little Prince), with book id 12345.

5. Operators with Spring EL

Operators that can be used in Spring EL are relational, logical and mathematical operators. We are using all of them in this example. Numbers.class is a class that contains int properties. Operators.class is a class with properties that will be used to hold results after applying Spring EL operators over the properties of Numbers.class.

Numbers.java

package com.javacodegeeks.snippets.enterprise;


public class Numbers {

	private int a;
	
	private int b;
	
	private int c;
	
	private int d;
	
	private int e;

	public int getA() {
		return a;
	}

	public void setA(int a) {
		this.a = a;
	}

	public int getB() {
		return b;
	}

	public void setB(int b) {
		this.b = b;
	}

	public int getC() {
		return c;
	}

	public void setC(int c) {
		this.c = c;
	}

	public int getD() {
		return d;
	}

	public void setD(int d) {
		this.d = d;
	}

	public int getE() {
		return e;
	}

	public void setE(int e) {
		this.e = e;
	}
}

Operators.java

package com.javacodegeeks.snippets.enterprise;


public class Operators {
	
		//Relational operators
	 
		private boolean equalTest;
	 
		private boolean notEqualTest;
	 
		private boolean lessThanTest;
	 
		private boolean lessThanOrEqualTest;
	 
		private boolean greaterThanTest;
	 
		private boolean greaterThanOrEqualTest;
	 
		//Logical operators
	 
		private boolean andTest;
	 
		private boolean orTest;
	 
		private boolean notTest;
	 
		//Mathematical operators
	 
		private double addTest;
	 
		private String addStringTest;
	 
		private double subtractionTest;
	 
		private double multiplicationTest;
	 
		private double divisionTest;
	 
		private double modulusTest ;
	 
		private double exponentialPowerTest;

		public boolean isEqualTest() {
			return equalTest;
		}

		public void setEqualTest(boolean equalTest) {
			this.equalTest = equalTest;
		}

		public boolean isNotEqualTest() {
			return notEqualTest;
		}

		public void setNotEqualTest(boolean notEqualTest) {
			this.notEqualTest = notEqualTest;
		}

		public boolean isLessThanTest() {
			return lessThanTest;
		}

		public void setLessThanTest(boolean lessThanTest) {
			this.lessThanTest = lessThanTest;
		}

		public boolean isLessThanOrEqualTest() {
			return lessThanOrEqualTest;
		}

		public void setLessThanOrEqualTest(boolean lessThanOrEqualTest) {
			this.lessThanOrEqualTest = lessThanOrEqualTest;
		}

		public boolean isGreaterThanTest() {
			return greaterThanTest;
		}

		public void setGreaterThanTest(boolean greaterThanTest) {
			this.greaterThanTest = greaterThanTest;
		}

		public boolean isGreaterThanOrEqualTest() {
			return greaterThanOrEqualTest;
		}

		public void setGreaterThanOrEqualTest(boolean greaterThanOrEqualTest) {
			this.greaterThanOrEqualTest = greaterThanOrEqualTest;
		}

		public boolean isAndTest() {
			return andTest;
		}

		public void setAndTest(boolean andTest) {
			this.andTest = andTest;
		}

		public boolean isOrTest() {
			return orTest;
		}

		public void setOrTest(boolean orTest) {
			this.orTest = orTest;
		}

		public boolean isNotTest() {
			return notTest;
		}

		public void setNotTest(boolean notTest) {
			this.notTest = notTest;
		}

		public double getAddTest() {
			return addTest;
		}

		public void setAddTest(double addTest) {
			this.addTest = addTest;
		}

		public String getAddStringTest() {
			return addStringTest;
		}

		public void setAddStringTest(String addStringTest) {
			this.addStringTest = addStringTest;
		}

		public double getSubtractionTest() {
			return subtractionTest;
		}

		public void setSubtractionTest(double subtractionTest) {
			this.subtractionTest = subtractionTest;
		}

		public double getMultiplicationTest() {
			return multiplicationTest;
		}

		public void setMultiplicationTest(double multiplicationTest) {
			this.multiplicationTest = multiplicationTest;
		}

		public double getDivisionTest() {
			return divisionTest;
		}

		public void setDivisionTest(double divisionTest) {
			this.divisionTest = divisionTest;
		}

		public double getModulusTest() {
			return modulusTest;
		}

		public void setModulusTest(double modulusTest) {
			this.modulusTest = modulusTest;
		}

		public double getExponentialPowerTest() {
			return exponentialPowerTest;
		}

		public void setExponentialPowerTest(double exponentialPowerTest) {
			this.exponentialPowerTest = exponentialPowerTest;
		}
		
	@Override
	public String toString() {
		return "equalTest : " + equalTest + " \n"
				+ "notEqualTest : " + notEqualTest + " \n"
				+ "lessThanTest : " + lessThanTest + " \n"
				+ "lessThanOrEqualTest : " + lessThanOrEqualTest + " \n" 
				+ "greaterThanTest : " + greaterThanTest + " \n"
				+ "greaterThanOrEqualTest : " + greaterThanOrEqualTest + " \n"
				+ "andTest : " + andTest + " \n" 
				+ "orTest : " + orTest + " \n" 
				+ "notTest : " + notTest + " \n" 
				+ "addTest : " + addTest + " \n"
				+ "addStringTest : " + addStringTest + " \n"
				+ "subtractionTest : " + subtractionTest + " \n" 
				+ "multiplicationTest "	+ multiplicationTest + " \n"
				+ "divisionTest : " + divisionTest + " \n"
				+ "modulusTest : " + modulusTest + " \n"
				+ "exponentialPowerTest : " + exponentialPowerTest;
	}
}

5.1 XML-based configuration

In applicationContext2.xml we define the operators in each property, using the expression language.

applicationContext2.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

	<bean id="numbersBean" class="com.javacodegeeks.snippets.enterprise.Numbers">
		<property name="a" value="100" />
		<property name="b" value="150" />
		<property name="c" value="200" />
		<property name="d" value="250" />
		<property name="e" value="300" />
	</bean>
	
	<bean id="operatorsBean" class="com.javacodegeeks.snippets.enterprise.Operators">
	<property name="equalTest" value="#{numbersBean.a == 100}" />
	<property name="notEqualTest" value="#{numbersBean.a != numbersBean.b}" />
	<property name="lessThanTest" value="#{numbersBean.b lt numbersBean.a}" />
	<property name="lessThanOrEqualTest" value="#{numbersBean.c le numbersBean.b}" />
	<property name="greaterThanTest" value="#{numbersBean.d > numbersBean.e}" />
	<property name="greaterThanOrEqualTest" value="#{numbersBean.d >= numbersBean.c}" />
	<property name="andTest" value="#{numbersBean.a == 100 and numbersBean.b lt 100}" />
	<property name="orTest" value="#{numbersBean.c == 150 or numbersBean.d lt 250}" />
	<property name="notTest" value="#{!(numbersBean.e == 300)}" />
	<property name="addTest" value="#{numbersBean.a + numbersBean.b}" />
	<property name="addStringTest" value="#{'hello' + '@' + 'world'}" />
	<property name="subtractionTest" value="#{numbersBean.d - numbersBean.c}" />
	<property name="multiplicationTest" value="#{numbersBean.a * numbersBean.e}" />
	<property name="divisionTest" value="#{numbersBean.e / numbersBean.a}" />
	<property name="modulusTest" value="#{numbersBean.e % numbersBean.b}" />
	<property name="exponentialPowerTest" value="#{numbersBean.a ^ 2}" />
	</bean>
 	
	
</beans>

5.2 Annotation-based configuration

The expressions are now set in the @Value annotations of Operators.java class.

Numbers.java

package com.javacodegeeks.snippets.enterprise;

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

@Component("numbersBean")
public class Numbers {

	@Value("100")
	private int a;
	
	@Value("150")
	private int b;
	
	@Value("200")
	private int c;
	
	@Value("250")
	private int d;
	
	@Value("300")
	private int e;

	public int getA() {
		return a;
	}

	public void setA(int a) {
		this.a = a;
	}

	public int getB() {
		return b;
	}

	public void setB(int b) {
		this.b = b;
	}

	public int getC() {
		return c;
	}

	public void setC(int c) {
		this.c = c;
	}

	public int getD() {
		return d;
	}

	public void setD(int d) {
		this.d = d;
	}

	public int getE() {
		return e;
	}

	public void setE(int e) {
		this.e = e;
	}
}

Operators.java

package com.javacodegeeks.snippets.enterprise;

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

@Component("operatorsBean")

public class Operators {
	
		//Relational operators
	 
		@Value("#{numbersBean.a == 100}") //true
		private boolean equalTest;
	 
		@Value("#{numbersBean.a != numbersBean.b}") //true
		private boolean notEqualTest;
	 
		@Value("#{numbersBean.b < numbersBean.a}") //false
		private boolean lessThanTest;
	 
		@Value("#{numbersBean.c <= numbersBean.b}") //false
		private boolean lessThanOrEqualTest;
	 
		@Value("#{numbersBean.d > numbersBean.e}") //false
		private boolean greaterThanTest;
	 
		@Value("#{numbersBean.d >= numbersBean.c}") //true
		private boolean greaterThanOrEqualTest;
	 
		//Logical operators
	 
		@Value("#{numbersBean.a == 100 and numbersBean.b < 100}") //false
		private boolean andTest;
	 
		@Value("#{numbersBean.c == 150 or numbersBean.d < 250}") //true
		private boolean orTest;
	 
		@Value("#{!(numbersBean.e == 300)}") //false
		private boolean notTest;
	 
		//Mathematical operators
	 
		@Value("#{numbersBean.a + numbersBean.b}") //250
		private double addTest;
	 
		@Value("#{'hello' + '@' + 'world'}") //hello@world
		private String addStringTest;
	 
		@Value("#{numbersBean.d - numbersBean.c}") //50
		private double subtractionTest;
	 
		@Value("#{numbersBean.a * numbersBean.e}") //30000
		private double multiplicationTest;
	 
		@Value("#{numbersBean.e / numbersBean.a}") //3
		private double divisionTest;
	 
		@Value("#{numbersBean.e % numbersBean.b}") //0.0
		private double modulusTest ;
	 
		@Value("#{numbersBean.a ^ 2}") //10000
		private double exponentialPowerTest;

		public boolean isEqualTest() {
			return equalTest;
		}

		public void setEqualTest(boolean equalTest) {
			this.equalTest = equalTest;
		}

		public boolean isNotEqualTest() {
			return notEqualTest;
		}

		public void setNotEqualTest(boolean notEqualTest) {
			this.notEqualTest = notEqualTest;
		}

		public boolean isLessThanTest() {
			return lessThanTest;
		}

		public void setLessThanTest(boolean lessThanTest) {
			this.lessThanTest = lessThanTest;
		}

		public boolean isLessThanOrEqualTest() {
			return lessThanOrEqualTest;
		}

		public void setLessThanOrEqualTest(boolean lessThanOrEqualTest) {
			this.lessThanOrEqualTest = lessThanOrEqualTest;
		}

		public boolean isGreaterThanTest() {
			return greaterThanTest;
		}

		public void setGreaterThanTest(boolean greaterThanTest) {
			this.greaterThanTest = greaterThanTest;
		}

		public boolean isGreaterThanOrEqualTest() {
			return greaterThanOrEqualTest;
		}

		public void setGreaterThanOrEqualTest(boolean greaterThanOrEqualTest) {
			this.greaterThanOrEqualTest = greaterThanOrEqualTest;
		}

		public boolean isAndTest() {
			return andTest;
		}

		public void setAndTest(boolean andTest) {
			this.andTest = andTest;
		}

		public boolean isOrTest() {
			return orTest;
		}

		public void setOrTest(boolean orTest) {
			this.orTest = orTest;
		}

		public boolean isNotTest() {
			return notTest;
		}

		public void setNotTest(boolean notTest) {
			this.notTest = notTest;
		}

		public double getAddTest() {
			return addTest;
		}

		public void setAddTest(double addTest) {
			this.addTest = addTest;
		}

		public String getAddStringTest() {
			return addStringTest;
		}

		public void setAddStringTest(String addStringTest) {
			this.addStringTest = addStringTest;
		}

		public double getSubtractionTest() {
			return subtractionTest;
		}

		public void setSubtractionTest(double subtractionTest) {
			this.subtractionTest = subtractionTest;
		}

		public double getMultiplicationTest() {
			return multiplicationTest;
		}

		public void setMultiplicationTest(double multiplicationTest) {
			this.multiplicationTest = multiplicationTest;
		}

		public double getDivisionTest() {
			return divisionTest;
		}

		public void setDivisionTest(double divisionTest) {
			this.divisionTest = divisionTest;
		}

		public double getModulusTest() {
			return modulusTest;
		}

		public void setModulusTest(double modulusTest) {
			this.modulusTest = modulusTest;
		}

		public double getExponentialPowerTest() {
			return exponentialPowerTest;
		}

		public void setExponentialPowerTest(double exponentialPowerTest) {
			this.exponentialPowerTest = exponentialPowerTest;
		}
		
	@Override
	public String toString() {
		return "equalTest : " + equalTest + " \n"
				+ "notEqualTest : " + notEqualTest + " \n"
				+ "lessThanTest : " + lessThanTest + " \n"
				+ "lessThanOrEqualTest : " + lessThanOrEqualTest + " \n" 
				+ "greaterThanTest : " + greaterThanTest + " \n"
				+ "greaterThanOrEqualTest : " + greaterThanOrEqualTest + " \n"
				+ "andTest : " + andTest + " \n" 
				+ "orTest : " + orTest + " \n" 
				+ "notTest : " + notTest + " \n" 
				+ "addTest : " + addTest + " \n"
				+ "addStringTest : " + addStringTest + " \n"
				+ "subtractionTest : " + subtractionTest + " \n" 
				+ "multiplicationTest "	+ multiplicationTest + " \n"
				+ "divisionTest : " + divisionTest + " \n"
				+ "modulusTest : " + modulusTest + " \n"
				+ "exponentialPowerTest : " + exponentialPowerTest;
	}
}

The only thing needed in applicationContext2.xml is to enable auto component-scan, as shown below:

applicationContext2.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
 	
	<context:component-scan base-package="com.javacodegeeks.snippets.enterprise" /> 
	
</beans>

5.3 Run the application

We are using App2.class to load the operatorsBean, as shown below:

App2.java

package com.javacodegeeks.snippets.enterprise;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {

	public static void main(String[] args) {
	
			ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
			Operators op = (Operators) context.getBean("operatorsBean");
			System.out.println(op.toString());
			context.close();
	}
}

After running the application the output is the one presented below:

equalTest : true 
notEqualTest : true 
lessThanTest : false 
lessThanOrEqualTest : false 
greaterThanTest : false 
greaterThanOrEqualTest : true 
andTest : false 
orTest : false 
notTest : false 
addTest : 250.0 
addStringTest : hello@world 
subtractionTest : 50.0 
multiplicationTest 30000.0 
divisionTest : 3.0 
modulusTest : 0.0 
exponentialPowerTest : 10000.0

6. Ternary operator (if-then-else) with Spring EL

Using the ternary operator in EL is the same as using the operators above. We are adding a new class, TernaryOperator.java that has one field that will hold the result after applying a Spring EL conditional expression over the fields of Numbers.java class.

TernaryOperator.java

package com.javacodegeeks.snippets.enterprise;

public class TernaryOperator {

	private boolean check;

	public boolean isCheck() {
		return check;
	}

	public void setCheck(boolean check) {
		this.check = check;
	}
	
	@Override
	public String toString(){
		return "TernaryOperator, checking if numbersBean.a is less than numbersBean.d : " + check;
	}
}

6.1 XML-based configuration

The new bean is defined in applicationContext2.xml.

applicationContext2.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

	<bean id="numbersBean" class="com.javacodegeeks.snippets.enterprise.Numbers">
		<property name="a" value="100" />
		<property name="b" value="150" />
		<property name="c" value="200" />
		<property name="d" value="250" />
		<property name="e" value="300" />
	</bean>
	
	<bean id="operatorsBean" class="com.javacodegeeks.snippets.enterprise.Operators">
	<property name="equalTest" value="#{numbersBean.a == 100}" />
	<property name="notEqualTest" value="#{numbersBean.a != numbersBean.b}" />
	<property name="lessThanTest" value="#{numbersBean.b lt numbersBean.a}" />
	<property name="lessThanOrEqualTest" value="#{numbersBean.c le numbersBean.b}" />
	<property name="greaterThanTest" value="#{numbersBean.d > numbersBean.e}" />
	<property name="greaterThanOrEqualTest" value="#{numbersBean.d >= numbersBean.c}" />
	<property name="andTest" value="#{numbersBean.a == 100 and numbersBean.b lt 100}" />
	<property name="orTest" value="#{numbersBean.c == 150 or numbersBean.d lt 250}" />
	<property name="notTest" value="#{!(numbersBean.e == 300)}" />
	<property name="addTest" value="#{numbersBean.a + numbersBean.b}" />
	<property name="addStringTest" value="#{'hello' + '@' + 'world'}" />
	<property name="subtractionTest" value="#{numbersBean.d - numbersBean.c}" />
	<property name="multiplicationTest" value="#{numbersBean.a * numbersBean.e}" />
	<property name="divisionTest" value="#{numbersBean.e / numbersBean.a}" />
	<property name="modulusTest" value="#{numbersBean.e % numbersBean.b}" />
	<property name="exponentialPowerTest" value="#{numbersBean.a ^ 2}" />
	</bean>
 	
 	<bean id="ternaryOperatorBean" class="com.javacodegeeks.snippets.enterprise.TernaryOperator">
		<property name="check" value="#{numbersBean.a lt numbersBean.d ? true : false}" />
	</bean>
	
</beans>

6.2 Annotation-based configuration

Using annotations, TernaryOperator.java class becomes as shown below:

TernaryOperator.java

package com.javacodegeeks.snippets.enterprise;

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

@Component("ternaryOperatorBean")
public class TernaryOperator {

	@Value("#{numbersBean.a < numbersBean.d ? true : false}")
	private boolean check;

	public boolean isCheck() {
		return check;
	}

	public void setCheck(boolean check) {
		this.check = check;
	}
	
	@Override
	public String toString(){
		return "TernaryOperator, checking if numbersBean.a is less than numbersBean.d : " + check;
	}
}

Now, the only thing needed in applicationContext2.xml is to enable the auto component scan, as described in all other annotation-based cases above.

applicationContext2.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">
 	
	<context:component-scan base-package="com.javacodegeeks.snippets.enterprise" /> 
	
</beans>

6.3 Run the application

We load the ternaryOperatorBean in App2.java class.

App2.java

package com.javacodegeeks.snippets.enterprise;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App2 {

	public static void main(String[] args) {
	
			ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
			Operators op = (Operators) context.getBean("operatorsBean");
			System.out.println(op.toString());
			TernaryOperator tern = (TernaryOperator) context.getBean("ternaryOperatorBean");
			System.out.println(tern.toString());
			context.close();
	}
}

The result is like the one shown below:

equalTest : true 
notEqualTest : true 
lessThanTest : false 
lessThanOrEqualTest : false 
greaterThanTest : false 
greaterThanOrEqualTest : true 
andTest : false 
orTest : false 
notTest : false 
addTest : 250.0 
addStringTest : hello@world 
subtractionTest : 50.0 
multiplicationTest 30000.0 
divisionTest : 3.0 
modulusTest : 0.0 
exponentialPowerTest : 10000.0
TernaryOperator, checking if numbersBean.a is less than numbersBean.d : true

7. Lists and Maps with Spring EL

Now, lets use Expression Language to get the values of a map and a list. Test.java class has two properties, a map and a list. TestMapList.java class has two fields, that will be used to hold specific elements from the list and the map of Test.java class selected using Sring EL expressions. The two classes are shown below:

Test.java

package com.javacodegeeks.snippets.enterprise;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {

	private Map<String, String> map;
	private List<String> list;
 
	public Test() {
		map = new HashMap<String, String>();
		map.put("key1", "Value 1");
		map.put("key2", "Value 2");
		map.put("key3", "Value 3");
 
		list = new ArrayList<String>();
		list.add("list0");
		list.add("list1");
		list.add("list2");
 
	}
 
	public Map<String, String> getMap() {
		return map;
	}
 
	public void setMap(Map<String, String> map) {
		this.map = map;
	}
 
	public List<String> getList() {
		return list;
	}
 
	public void setList(List<String> list) {
		this.list = list;
	}
	
}

TestMapList.java

package com.javacodegeeks.snippets.enterprise;


public class TestMapList {
	
	private String mapElement;
 
	private String listElement;
  
	public String getMapElement() {
		return mapElement;
	}

	public void setMapElement(String mapElement) {
		this.mapElement = mapElement;
	}

	public String getListElement() {
		return listElement;
	}

	public void setListElement(String listElement) {
		this.listElement = listElement;
	}

	@Override
	public String toString() {
		return "TestMapList [mapElement=" + mapElement + ", listElement=" + listElement + "]";
	}
	
}

7.1 XML-based configuration

In applicationContext3.xml we define the two beans:

applicationContext3.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

	<bean id="testBean" class="com.javacodegeeks.snippets.enterprise.Test" />
	
	<bean id="testMapListBean" class="com.javacodegeeks.snippets.enterprise.TestMapList">
		<property name="mapElement" value="#{testBean.map['key1']}" />
		<property name="listElement" value="#{testBean.list[0]}" />
	</bean>

	
</beans>

7.2 Annotation-based configuration

Using annotations, the classes become as shown below:

Test.java

package com.javacodegeeks.snippets.enterprise;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;

@Component("testBean")
public class Test {

	private Map<String, String> map;
	private List<String> list;
 
	public Test() {
		map = new HashMap<String, String>();
		map.put("key1", "Value 1");
		map.put("key2", "Value 2");
		map.put("key3", "Value 3");
 
		list = new ArrayList<String>();
		list.add("list0");
		list.add("list1");
		list.add("list2");
 
	}
 
	public Map<String, String> getMap() {
		return map;
	}
 
	public void setMap(Map<String, String> map) {
		this.map = map;
	}
 
	public List<String> getList() {
		return list;
	}
 
	public void setList(List<String> list) {
		this.list = list;
	}
	
}

TestMapList.java

package com.javacodegeeks.snippets.enterprise;

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

@Component("testMapListBean")
public class TestMapList {
	
	@Value("#{testBean.map['key1']}")
	private String mapElement;
 
	@Value("#{testBean.list[0]}")
	private String listElement;
  
	public String getMapElement() {
		return mapElement;
	}

	public void setMapElement(String mapElement) {
		this.mapElement = mapElement;
	}

	public String getListElement() {
		return listElement;
	}

	public void setListElement(String listElement) {
		this.listElement = listElement;
	}

	@Override
	public String toString() {
		return "TestMapList [mapElement=" + mapElement + ", listElement=" + listElement + "]";
	}
	
}

Whereas, applicationContext3.xml is now:

applicationContext3.xm

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

<context:component-scan base-package="com.javacodegeeks.snippets.enterprise" /> 
	
</beans>

7.3 Run the application

We load the beans in App3.java class.

App3.java

package com.javacodegeeks.snippets.enterprise;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App3 {

	public static void main(String[] args) {
	
			ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext3.xml");

			TestMapList testMapList = (TestMapList) context.getBean("testMapListBean");
			System.out.println(testMapList.toString());
			context.close();
	}
}

The result is the one shown below:

TestMapList [mapElement=Value 1, listElement=list0]

8. Regular Expressions with Spring EL

In order to check how regular expressions work with SpEL, we are going to enrich our latest example with email check functionality. We are adding a new property email to Test.java class that will hold the email to be checked for validity. Additionaly we are creating a new class, TestRegEx.java that will hold the result of Spring EL regular expressions check results in its fields. For this example we are going to check the email property value of Test.java with a regular expression used for emails so as to examine whether it is a valid email address. We will also try to match a number to a regular expression used for digits to check if it is a digit.

Test.java

package com.javacodegeeks.snippets.enterprise;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Test {

	private Map<String, String> map;
	private List<String> list;
	private String email;
 
	public Test() {
		map = new HashMap<String, String>();
		map.put("key1", "Value 1");
		map.put("key2", "Value 2");
		map.put("key3", "Value 3");
 
		list = new ArrayList<String>();
		list.add("list0");
		list.add("list1");
		list.add("list2");
		
		email = "hello@javacodegeeks.com";
 
	}

	public Map<String, String> getMap() {
		return map;
	}
 
	public void setMap(Map<String, String> map) {
		this.map = map;
	}
 
	public List<String> getList() {
		return list;
	}
 
	public void setList(List<String> list) {
		this.list = list;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}	
}

TestRegEx.java

package com.javacodegeeks.snippets.enterprise;


public class TestRegEx {
	
	private String regEx;
	

	private String regExResult;

	private String numberResult;
 
	public String getRegEx() {
		return regEx;
	}

	public void setRegEx(String regEx) {
		this.regEx = regEx;
	}
	
	public String getRegExResult() {
		return regExResult;
	}

	public void setRegExResult(String regExResult) {
		this.regExResult = regExResult;
	}

	public String getNumberResult() {
		return numberResult;
	}

	public void setNumberResult(String numberResult) {
		this.numberResult = numberResult;
	}

	@Override
	public String toString() {
		return "TestRegex :  \n Does testBean.email match the ^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$ " 
	+ regExResult + "\n Is 100 a valid number ? " + numberResult;
				
	}

}

8.1 XML-based configuration

In applicationContext3.xml we add the new bean.

applicationContext3.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

	<bean id="testBean" class="com.javacodegeeks.snippets.enterprise.Test" />
	
	<bean id="testMapListBean" class="com.javacodegeeks.snippets.enterprise.TestMapList">
		<property name="mapElement" value="#{testBean.map['key1']}" />
		<property name="listElement" value="#{testBean.list[0]}" />
	</bean>

	<bean id="testRegExBean" class="com.javacodegeeks.snippets.enterprise.TestRegEx">
		<property name="regEx" value="^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})

quot; />
<property name="regExResult" value="#{(testBean.email matches '^[_A-Za-z0-9-\+]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})

8.2 Annotation-based configuration

Now, let's see what happens when we use annotations:

Test.java

package com.javacodegeeks.snippets.enterprise;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Component;

@Component("testBean")
public class Test {

	private Map<String, String> map;
	private List<String> list;
	private String email;
 
	public Test() {
		map = new HashMap<String, String>();
		map.put("key1", "Value 1");
		map.put("key2", "Value 2");
		map.put("key3", "Value 3");
 
		list = new ArrayList<String>();
		list.add("list0");
		list.add("list1");
		list.add("list2");
		
		email = "hello@javacodegeeks.com";
 
	}

	public Map<String, String> getMap() {
		return map;
	}
 
	public void setMap(Map<String, String> map) {
		this.map = map;
	}
 
	public List<String> getList() {
		return list;
	}
 
	public void setList(List<String> list) {
		this.list = list;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}	
}

TestRegEx.java

package com.javacodegeeks.snippets.enterprise;

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

@Component("testRegExBean")
public class TestRegEx {
	
	@Value("^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})

quot;)
private String regEx;

@Value("#{(testBean.email matches testRegExBean.regEx)== true ? '-Yes there is a match.' : '-No there is no match.' }")
private String regExResult;

@Value("#{ ('100' matches '\\d+') == true ? '-Yes this is digit.' : '-No this is not a digit.' }")
private String numberResult;

public String getRegEx() {
return regEx;
}

public void setRegEx(String regEx) {
this.regEx = regEx;
}

public String getRegExResult() {
return regExResult;
}

public void setRegExResult(String regExResult) {
this.regExResult = regExResult;
}

public String getNumberResult() {
return numberResult;
}

public void setNumberResult(String numberResult) {
this.numberResult = numberResult;
}

@Override
public String toString() {
return "TestRegex : \n Does testBean.email match the ^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$ "
+ regExResult + "\n Is 100 a valid number ? " + numberResult;

}

}
applicationContext3.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">

	
<context:component-scan base-package="com.javacodegeeks.snippets.enterprise" /> 
	
</beans>

8.3 Run the application

Now, let's use App3.java class again:

App3.java

package com.javacodegeeks.snippets.enterprise;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App3 {

	public static void main(String[] args) {
	
			ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("applicationContext3.xml");

			TestMapList testMapList = (TestMapList) context.getBean("testMapListBean");
			System.out.println(testMapList.toString());
			
			TestRegEx testRegEx = (TestRegEx) context.getBean("testRegExBean");
			System.out.println(testRegEx.toString());
			
			context.close();
	}
}
TestMapList [mapElement=Value 1, listElement=list0]
TestRegex :  
 Does testBean.email match the ^[_A-Za-z0-9-\+]+(\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\.[A-Za-z0-9]+)*(\.[A-Za-z]{2,})$ -Yes there is a match.
 Is 100 a valid number ? -Yes this is digit.

9. ExpressionParser with Spring EL

In order to use the ExpressionParser provided by the Spring API to evaluate exressions in Spring, we are creating ExpressionParserApp.java class. We are creating a new SpelExpressionParser and with its parseExpression(String arg0) API method we parse the expression string and return an Expression object that will be evaluated. We are using a literal expression, a method invocation, and we are also creating a new Test object and evaluate its email field.

ExpressionParserApp.java

package com.javacodegeeks.snippets.enterprise;


	import org.springframework.expression.Expression;
	import org.springframework.expression.ExpressionParser;
	import org.springframework.expression.spel.standard.SpelExpressionParser;
	import org.springframework.expression.spel.support.StandardEvaluationContext;
	 
	public class ExpressionParserApp {
		public static void main(String[] args) {
	 
			ExpressionParser parser = new SpelExpressionParser();
	 
			//literal expressions 
			Expression exp = parser.parseExpression("'Hello World'");
			String msg1 = exp.getValue(String.class);
			System.out.println(msg1);
	 
			//method invocation
			Expression exp2 = parser.parseExpression("'Hello World'.length()");  
			int msg2 = (Integer) exp2.getValue();
			System.out.println(msg2);
	 
			//Mathematical operators
			Expression exp3 = parser.parseExpression("100 * 2");  
			int msg3 = (Integer) exp3.getValue();
			System.out.println(msg3);
	 
			//create an test object
			Test test = new Test();
			//test EL with test object
			StandardEvaluationContext testContext = new StandardEvaluationContext(test);
	 
			//display the value of test.email property
			Expression exp4 = parser.parseExpression("email");
			String msg4 = exp4.getValue(testContext, String.class);
			System.out.println(msg4);
	 
			//test if test.email == 'Hello@javacodegeeks.com'
			Expression exp5 = parser.parseExpression("email == 'Hello@javacodegeeks.com'");
			boolean msg5 = exp5.getValue(testContext, Boolean.class);
			System.out.println(msg5);
	}
}

9.1 Run the application

After running ExpressionParserApp.java the result is like the one below:

Hello World
11
200
hello@javacodegeeks.com
false

 
This was an example of Expression Language in Spring 3.
 

Download the Eclipse project of this tutorial : SpringExpressionLanguageExample.zip

)== true ? '-Yes there is a match.' : '-No there is no match.' }" />
<property name="numberResult" value="#{ ('100' matches '\d+') == true ? '-Yes this is digit.' : '-No this is not a digit.' }" />
</bean>

</beans>

8.2 Annotation-based configuration

Now, let's see what happens when we use annotations:

Test.java

TestRegEx.java

applicationContext3.xml

8.3 Run the application

Now, let's use App3.java class again:

App3.java

9. ExpressionParser with Spring EL

In order to use the ExpressionParser provided by the Spring API to evaluate exressions in Spring, we are creating ExpressionParserApp.java class. We are creating a new SpelExpressionParser and with its parseExpression(String arg0) API method we parse the expression string and return an Expression object that will be evaluated. We are using a literal expression, a method invocation, and we are also creating a new Test object and evaluate its email field.

ExpressionParserApp.java

9.1 Run the application

After running ExpressionParserApp.java the result is like the one below:

 
This was an example of Expression Language in Spring 3.
 

Download the Eclipse project of this tutorial : SpringExpressionLanguageExample.zip

Theodora Fragkouli

Theodora has graduated from Computer Engineering and Informatics Department in the University of Patras. She also holds a Master degree in Economics from the National and Technical University of Athens. During her studies she has been involved with a large number of projects ranging from programming and software engineering to telecommunications, hardware design and analysis. She works as a junior Software Engineer in the telecommunications sector where she is mainly involved with projects based on Java and Big Data technologies.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
ooxaam
ooxaam
6 years ago

Can we iterate over a list using Spel?

Fateh
Fateh
5 years ago
Reply to  ooxaam

Hi
Yes you can iterate over the List using spEL

public static void main(String[] args) {
List myList = new ArrayList(Arrays.asList(0, 1, 2, 3, 4, 5));

ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext(myList);

context.setVariable(“myList”, myList);

List newList = parser.parseExpression(“#myList”).getValue(context, List.class);

for (int index : newList){
System.out.println(“value is “+ newList.get(index));
}

}

Back to top button