I am a software architect and loud-mouth on the design and development of enterprise softwares. Also I am a visionary who loves Big Data and Start-Up Chris is a DZone MVB and is not an employee of DZone and has posted 11 posts at DZone. You can read more from them at their website. View Full User Profile

Spring and ehCache

10.24.2012
| 5179 views |
  • submit to reddit

In this quick tip, I would like to share some simple code on how to use spring and ehcache by consuming following annotations:

  1. @Cacheable
  2. @CacheEvict

Step 0: Maven

 On top of basic spring dependancies, you need to add ehcach dependancy too. Following snipped is the mavendependancy of ehcache:

        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>${ehcache.version}</version>
            <type>pom</type>
        </dependency>

 <!--break-->

Also the repository of it is:

        <repository>
            <id>sourceforge</id>
            <name>sourceforge</name>
            <url>https://oss.sonatype.org/content/repositories/sourceforge-releases/</url>
        </repository>

 

Step 1: Value Object

The transfer object that I would like to cache is called Person. You can find its code in the following table, the most important part is this value object must be serializable:

 public class Person implements Serializable {
    private String firstName, lastName;
    // setter and getter

}  

Step 2: Service

You can see the code of this service in following table:

@Service
public class PersonService {
    private static final Logger LOG = LoggerFactory.getLogger(PersonService.class);
    private final Map<String, Person> people = new ConcurrentHashMap<String, Person>();

    @PostConstruct
    public void init() {
        savePerson(new Person("Martin", "Fowler"));
        savePerson(new Person("James", "Gosling"));
    }

    /**
     *
     * @param firstName first name
     * @return {@link Person} that will be cached because of {@link Cacheable} under a name of <b>person</b>
     */
    @Cacheable("person")
    public Person getPerson(final String firstName) {
        LOG.info(String.format("Loading a person with firstName of : %s", firstName));
        return people.get(firstName);
    }

    /**
     * By usage of {@link CacheEvict} framework is being told to cache this input parameter in
     * a cache called <b>person</b>. Also the key for the cache is determined by an SpEl like:
     * <b>#person.firstName</b>
     * @param person {@link Person}
     */
    @CacheEvict(value = "person", key = "#person.firstName")
    public void savePerson(final Person person) {
        LOG.info(String.format("Saving a person with firstName of : %s", person.getFirstName()));
        people.put(person.getFirstName(), person);
    }
} 

 Step 3: ehCache Configuration

ehCache needs some basic configuration for its functioning, for this example we are using following XML:

<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <cache name="person"
           maxElementsInMemory="100"
           eternal="false"
           timeToIdleSeconds="120"
           timeToLiveSeconds="120"
           overflowToDisk="true"
           maxElementsOnDisk="10000000"
           diskPersistent="false"
           diskExpiryThreadIntervalSeconds="120"
           memoryStoreEvictionPolicy="LRU"/>

</ehcache>

 To configure for spring to use ehCache as cache manager, following code snippet is required:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:cache="http://www.springframework.org/schema/cache"
       xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
    <cache:annotation-driven/>

    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
          p:cacheManager-ref="ehcache"/>
    <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
          p:configLocation="classpath:com/chrisshayan/sample/cache/ehcache.xml"/>
</beans> 

Step 4: Running the code

To execute the code, there are so many ways. For this example following code has been used:

@Configuration
@ComponentScan("com.chrisshayan.sample.cache")
@ImportResource("classpath:com/chrisshayan/sample/cache/personCache.xml")
public class CacheConfiguration {
    @Autowired
    PersonService personService;

    @PostConstruct
    public void showCache() {
        personService.getPerson("Martin");
        personService.getPerson("Martin");

        personService.getPerson("James");
        personService.getPerson("James");

        personService.savePerson(new Person("Key", "Value"));
        personService.getPerson("Key");
        personService.getPerson("Key");
    }

    public static void main(String[] args) {
        new AnnotationConfigApplicationContext(CacheConfiguration.class);
    }
}

 

If you execute the above codes, you will see within the log following messages:


0 [main] INFO com.chrisshayan.sample.cache.PersonService - Saving a person with firstName of : Martin
0 [main] INFO com.chrisshayan.sample.cache.PersonService - Saving a person with firstName of : James
Oct 24, 2012 11:30:46 PM org.springframework.cache.ehcache.EhCacheManagerFactoryBean afterPropertiesSet
INFO: Initializing EHCache CacheManager
515 [main] INFO com.chrisshayan.sample.cache.PersonService - Loading a person with firstName of : Martin
531 [main] INFO com.chrisshayan.sample.cache.PersonService - Loading a person with firstName of : James
531 [main] INFO com.chrisshayan.sample.cache.PersonService - Saving a person with firstName of : Key
562 [main] INFO com.chrisshayan.sample.cache.PersonService - Loading a person with firstName of : Key

As you notice despite getPerson method by same input parameters have been called twice but there is solely one log per each. The reason is after the first time, value is cached by ehcache and on second call onwards ehcache will return the value. 

 

5
Your rating: None Average: 5 (1 vote)
Published at DZone with permission of Chris Shayan, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)