Home  >  Spring 4

Spring 4 Ehcache Configuration Example with @Cacheable Annotation

By Arvind Rai, March 16, 2015
In this page, we will learn Spring 4 Ehcache configuration example with @Cacheable annotation. Ehcache manages cache for boosting performance. Spring provides @Cacheable annotation that uses cache name defined in Ehcache xml file. Spring provides EhCacheManagerFactoryBean and EhCacheCacheManager classes to configure and instantiate Ehcache. The configuration class must be annotated with @EnableCaching annotation which enables annotation driven cache management. Here we will provide a complete example for Spring Ehcache Configuration.

build.gradle

Find the Gradle file to resolve JAR dependency for Spring and Ehcache.
build.gradle
apply plugin: 'java'
apply plugin: 'eclipse'
archivesBaseName = 'concretepage'
version = '1' 
repositories {
        mavenCentral()
}
dependencies {
	compile 'org.springframework.boot:spring-boot-starter:1.2.2.RELEASE'
	compile 'org.springframework:spring-context-support:4.1.5.RELEASE'
	compile 'net.sf.ehcache:ehcache-core:2.6.10'
}  

Project Structure in Eclipse

Find the project structure in eclipse that will help to learn fast.
Spring 4 Ehcache Configuration Example with @Cacheable Annotation

Configuration Class for EhCacheManagerFactoryBean and EhCacheCacheManager

The configuration class will be annotated with @EnableCaching annotation and we need to create bean for EhCacheManagerFactoryBean and EhCacheCacheManager class.

@EnableCaching: It enables annotation driven cache management in spring and is same as using <cache:annotation-driven />.
EhCacheManagerFactoryBean: Assign ehcache XML file by calling EhCacheManagerFactoryBean.setConfigLocation(). By passing true to setShared() method, we enable our cache to be shared as singleton at the ClassLoader level. By default it is set to false.
EhCacheCacheManager: This is a CacheManager backed by an EhCache. We can instantiate it by passing argument of EhCacheManagerFactoryBean.getObject().

Find the Configuration file.
AppConfig.java
package com.concretepage;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
@Configurable
@EnableCaching
public class AppConfig {
	@Bean
	public Employee getEmployee(){
	        return  new Employee();	
	}
	@Bean
	public CacheManager getEhCacheManager(){
	        return  new EhCacheCacheManager(getEhCacheFactory().getObject());
	}
	@Bean
	public EhCacheManagerFactoryBean getEhCacheFactory(){
		EhCacheManagerFactoryBean factoryBean = new EhCacheManagerFactoryBean();
		factoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
		factoryBean.setShared(true);
		return factoryBean;
	}
} 
The equivalent ehcache configuration in spring xml is given below.
<cache:annotation-driven />
<bean id="employee" class="com.concretepage.Employee"/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" 
                p:cache-manager-ref="ehcache"/>
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
                p:config-location="classpath:ehcache.xml" p:shared="true"/> 

ehcache.xml

Find the sample ehcache.xml file. We have created a cache with the name empcache that will be used by spring @Cacheable annotation. Here maximum 5000 elements will be cached in memory and after that it will overflow to local disk. Any element will expire if it is idle for more than 200 seconds and alive for more than 500 seconds.
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="ehcache.xsd"
     updateCheck="true" monitoring="autodetect" dynamicConfig="true">
    <cache name="empcache" 
      maxEntriesLocalHeap="5000"
      maxEntriesLocalDisk="1000" 
      eternal="false" 
      diskSpoolBufferSizeMB="20" 
      timeToIdleSeconds="200" 
      timeToLiveSeconds="500" 
      memoryStoreEvictionPolicy="LFU" 
      transactionalMode="off">
        <persistence strategy="localTempSwap"/>
    </cache>
  </ehcache> 

Using @Cacheable on Bean Method

If we annotate our bean method by Spring @Cacheable annotation, it declares that it will be cached. We need to provide cache name defined in ehcache.xml. In our example we have a cache named as empcache in ehcache.xml and we have provided this name in @Cacheable. Spring will hit the method for the first time. The result of this method will be cached and for same argument value, spring will not hit the method every time. Once the cache is expired, then the spring will hit the method again for the same argument value.
Employee.java
package com.concretepage;
import org.springframework.cache.annotation.Cacheable;
public class Employee {
	@Cacheable("empcache") 
	public String getEmployee(int empId){
		System.out.println("---Inside getEmployee() Method---");
		if(empId==1){			
			return "Shankar";
		}else{
			return "Vishnu";
		}
	}
} 

Test Spring Ehcache Application

Now we create a main method to test the application. Here if we call the method passing a value as an argument for the first time, spring will hit the method. And for next hit, if we pass the same argument value, we will get result from cache not by running method.
SpringDemo.java
package com.concretepage;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringDemo {
    public static void main(String... args) {
    	 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
  	 ctx.register(AppConfig.class);
  	 ctx.refresh();
         Employee employee=(Employee) ctx.getBean(Employee.class);
            
         //calling getEmployee method first time.
         System.out.println("---Fetch Employee with id 1---");
         System.out.println("Employee:"+ employee.getEmployee(1));
            
         //calling getEmployee method second time. This time, method will not execute.
         System.out.println("---Again Fetch Employee with id 1, result will be fetched from cache---");
         System.out.println("Employee:"+employee.getEmployee(1));
            
         //calling getEmployee method third time with different value.
         System.out.println("---Fetch Employee with id 2---");
          System.out.println("Employee:"+employee.getEmployee(2));
     } 
} 
Find the output.
17:06:49.301 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'getEmployee'
---Fetch Employee with id 1---
---Inside getEmployee() Method---
17:06:49.323 [main] DEBUG net.sf.ehcache.store.disk.Segment - put added 0 on heap
Employee:Shankar
---Again Fetch Employee with id 1, result will be fetched from cache---
Employee:Shankar
---Fetch Employee with id 2---
---Inside getEmployee() Method---
17:06:49.327 [main] DEBUG net.sf.ehcache.store.disk.Segment - put added 0 on heap
Employee:Vishnu
17:06:49.332 [empcache.data] DEBUG net.sf.ehcache.store.disk.Segment - fault removed 0 from heap
17:06:49.332 [empcache.data] DEBUG net.sf.ehcache.store.disk.Segment - fault added 0 on disk 

Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
FIND MORE TUTORILAS
comments powered by Disqus








Copyright ©2017 concretepage.com, all rights reserved |Privacy Policy | Contact Us