ehcache-spring-maven example

Java, Spring Comments Off

Level: Beginner: Maven –  Spring – Ehcache
Objective: Creating a Spring based application, with caching [using ehcache].

Cache is a component that transparently stores data in such a way that any future request to this data could be served faster without fetching from the original source again.

Ehcache: http://ehcache.org/

Uses:

  • Ehcache can be used for general purpose caching as we are going to see in this example
  • Ehcache can be used in a second level cache in hibernate[ not explained here ].

Implementation:

  • Physical implementation is either in-memory or on disk.
  • Logical representation is through the classes provided by ehcache.jar

Basically, Ehcache consists of CacheManager, which manages cache [Creation/Access-to/Removal of cache]
Cache contain ‘Elements’ which are key-value pairs.

More theory: http://ehcache.org/documentation/get-started/concepts

Let’s learn by hands-on.

Let’s create a Maven Spring project in eclipse IDE, and we see how to  use ehcache to cache the data, and the configuration involved in the process. I am keeping this example to have components that are required only to demonstrate our goal [no unnecessary jars]

–          Create a maven project in eclipse

create maven project

 

ehcache-4

ehcache-5

 

 

Let us add spring and ehcache dependencies to our project by adding them to pom.xml

How do you get the dependency? Just Search on the maven repository ..

http://mvnrepository.com/artifact/org.springframework/spring-core/3.0.0.RELEASE

http://mvnrepository.com/artifact/net.sf.ehcache/ehcache/2.8.0

ehcache-6

 

 

 

 

 

 

A snapshot of the  Maven dependencies after adding the dependencies in pom.xml, looks like below:

ehcache-7

 

 

Note: Sometimes if this doesn’t get refreshed automatically , please do a maven command to sync maven and eclipse  using the maven command ‘mvn eclipse:eclipse

First  Create a spring configuration file to define your beans

Note: we will add more xsd as we proceed further to support required bean and tags.

In this tutorial, we use @Cacheable annotation to mark a bean as cacheable.

@Cacheable annotation requires spring-context [any version] and  Spring version 3.1.x +
Let’s use 3.2.6.RELEASE for both for this tutorial.

http://mvnrepository.com/artifact/org.springframework/spring-context/3.2.6.RELEASE

http://mvnrepository.com/artifact/org.springframework/spring-core/3.2.6.RELEASE

Adding spring-context dependency to pom.xml added a total of five jars to Maven dependency:

ehcache-8

The  org.springframework.cache.ehcache package is not found! so far.

Add the following dependency to resolve the same:
http://mvnrepository.com/artifact/org.springframework/spring-context-support/3.2.6.RELEASE

This will add two jar to Maven dependencies.

ehcache-9

 

 

Now that all dependencies and configuration is set, we will look at the complete project :

 

 

Pom.xml

Spring-config.xml
  • ehcache.xml

Employee.java

public class Employee {
private int id;
private String name;
private String designation;

public Employee(int id, String name, String designation) {
super();
this.id = id;
this.name = name;
this.designation = designation;
}

public int getId() {
return id;
}

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

@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", designation="
+ designation + "]";
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDesignation() {
return designation;
}

public void setDesignation(String designation) {
this.designation = designation;
}
}
  • EmployeeDAO.java
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;

@Component("employeeDAO")
public class EmployeeDAO {

	@Cacheable(value = "employeeCache")
	public List<Employee> getEmployees() {
		Random random = new Random();
		int randomid = random.nextInt(9999);
		System.out.println("*** Creating a list of employees and returning the list ***");
		List<Employee> employees = new ArrayList<Employee>(5);
		employees.add(new Employee(randomid, "Ben", "Architect"));
		employees.add(new Employee(randomid + 1, "Harley", "Programmer"));
		employees.add(new Employee(randomid + 2, "Peter", "BusinessAnalyst"));
		employees.add(new Employee(randomid + 3, "Sasi", "Manager"));
		employees.add(new Employee(randomid + 4, "Abhi", "Designer"));
		return employees;
	}

	@Cacheable(value = "employeeCache", key = "#name")
	public Employee getEmployee(String name, List<Employee> employees) {
		System.out.println("*** Get the employee using name : " + name + " ***");
		Employee emp = null;
		for (Employee employee : employees) {
			if (employee.getName().equalsIgnoreCase(name)) {
				emp = employee;
			}
		}
		return emp;
	}

}

 

Main.java

import java.util.List;

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

public class Main {

	public static void main(String[] args) {
		List<Employee> employees;
		Employee employee;
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		EmployeeDAO dao = (EmployeeDAO)context.getBean("employeeDAO");
		employees = dao.getEmployees();
		System.out.println(employees.toString());
		System.out.println("---------------------------------------------------");
		employees = dao.getEmployees();
		System.out.println(employees.toString());
		System.out.println("---------------------------------------------------");
		employees = dao.getEmployees();
		System.out.println(employees.toString());
		System.out.println("---------------------------------------------------");
		employee = dao.getEmployee("Harley", employees);
		System.out.println(employee.toString());
		employee = dao.getEmployee("Harley", employees);
		System.out.println(employee.toString());
		
	}
} 

ehcache-11-output

 

What do we understand from above output?

  • First time, when getEmployees() is called, the actual method inside the DAO is executed, list is created and returned.

On the subsequent calls, the list of employee is retrieved from the cache.

  • First time, when getEmployee() with the name “Harley” is called, getEmployee() in the DAO is executed and the employee is retrieved.

On the subsequent calls, the employee is retrieved from the cache.

We are done.. Happy Learning!

Going further to the details:

  • All the attributes that could be used in cache in ehcache configuration file are well explained in the section ‘Cache configuration’  in this documentation of ehcache. http://ehcache.org/ehcache.xml

About  EhCacheManagerFactoryBean

In spring-config.xml,  we have configured the ehcache bean :

<bean id=”ehcache” class=”org.springframework.cache.ehcache.EhCacheManagerFactoryBean”>
       <property name=”configLocation” value=”classpath:ehcache.xml” />
</bean>

This  bean has two properties:

  1. configLocation –  Optional.
    – Used to specify location of ehcache configuration file.- Default is “ehcache.xml” in the root of the class path, or if not found, refers “ehcache-failsafe.xml” in the EhCache jar (default EhCache initialization)
  2. Shared – Optional.
    As per the documentation from ‘org.springframework.cache.ehcache’, it states  “Set whether the EhCache CacheManager should be shared (as a singleton at the VM level)  or independent (typically local within the application).- Default is “false”, creating an independent instance.”

Note: A mistake that can happen while invoking the method that is cached.
Note: There is a common mistake that could happen here,

EmployeeDAO dao = (EmployeeDAO)context.getBean(“employeeDAO”);

            dao.getEmployees();

Instead of getting the EmployeeDAO from the context, if you try to create one using the new operator,the caching WONT work. Guess why?.. The EmployeeDAO will not get the spring annotations applied because it is not spring-managed.

EmployeeDAO dao = new EmployeeDAO();

            dao.getEmployees(); // caching doesn’t work as the DAO bean creation is not spring managed

Things to try out

–          We can use custom annotations

Reference: http://docs.spring.io/spring/docs/3.1.0.M1/spring-framework-reference/html/cache.html

  •  There are many more attributes that can be used to define a cache in the file ehcache.xml
  •  Also read http://ehcache.org/documentation/user-guide/configuration
  •  Try changing ‘maxElementsInMemory’ with ‘maxEntriesLocalHeap
  •  Another way of setting the property of cacheManager. Note the ‘p:cache-manager-ref
    <bean id=”cacheManager” class=”org.springframework.cache.ehcache.EhCacheCacheManager”
      p:cache-manager-ref=”ehcache” />
  • Note to use xmlns:p=”http://www.springframework.org/schema/p”
  • Also in pom.xml , you might have to use the dependency for spring-context-support

More to learn/read-on:

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cache.html

Search

Back to Top