Spring Expression Language Example (original) (raw)

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 #{ }.

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:

2. Add Spring 3.2.3 dependency

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 " title="undefined" rel="noopener noreferrer">http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 com.javacodegeeks.snippets.enterprise springexample 0.0.1-SNAPSHOT

<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>

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:

<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>

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

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

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:

<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>

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

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

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

<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>
 

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

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

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

<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>

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

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

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

<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>

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

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

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

<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,})$ "

}

}

applicationContext3.xml

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

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

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