Thursday, January 27, 2011

EhCache integration with Spring

Previously I've used EhCache several times in applications where we would manage and retrieve cached items within our code. For example to store a cached item we may see the following:

cache.put(new Element(key, value));

And to get a cached item we may do the following:

            Element element = cache.get(key);
            if (null != element) {
                return element.getObjectValue();
            }

On top of that we need to manage the caches using code similar to the following:
            manager.addCache(name);
            cache = manager.getCache(name);


Several times I've asked myself 'Wouldn't it be nice if the caching mechanims were more transparent?". Caching is one of those "behind the scenes" type of operations and I never did felt comfortable putting it into our application code even if we layered it properly in multiple service tiers.

Today, I learned of EhCache and spring integration which was so easy to setup with little or no cache management. The idea is quite simple: Cache the results returned from method calls.

Here's an example of how you would declare that the results of a method be cacheable:

    @Cacheable(cacheName="mustererMouseObservations")    public Mouse getMouseObservations(String barcode) throws MustererException;

It automatically creates a cache called "mustererMouseObservations" and stores the returned result. Next time the method is invoked with the same arguments, the object returned is taken from the cache!

To declare the ehcache annotations, add the following to the spring bean wiring file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
    
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring        http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.0.xsd"
        >

    <!-- Scans the classpath of this application for @Components to deploy as beans -->
    <context:component-scan base-package="au.org.australianphenomics" />
    <!-- Caching of Spring Method results -->
    <ehcache:annotation-driven create-missing-caches="true" cache-manager="ehCacheManager" />
    <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
        <!--property name="configLocation" value="classpath:META-INF/spring/ehcache.xml" /-->
    </bean>

If you're using Maven like I am you can add the dependency in your pom file:
        <!--  EhCache annotations -->
        <dependency>
          <groupId>com.googlecode.ehcache-spring-annotations</groupId>
          <artifactId>ehcache-spring-annotations</artifactId>
          <version>1.1.2</version>
        </dependency>

And that's it! There's no need to explicity add items to the cache, or retrieve from the cache. It's all done transparently!

Note:
Be aware that cacheable methods that are self-invocating a method on itself, are not cacheable as stated as follows:

Self-Invocation

Only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual cache interception at runtime even if the invoked method is marked with @Cacheable.


References:
http://code.google.com/p/ehcache-spring-annotations/
http://ehcache.org/recipes/spring-annotations.html
http://developers-blog.org/blog/default/2010/06/07/Caching-Example-with-Spring-Annotations-and-Ehcache
http://onjavahell.blogspot.com/2009/09/annotation-driven-caching-with-ehcache.html

No comments:

Post a Comment