Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Spring and ehCache

DZone's Guide to

Spring and ehCache

· Java Zone
Free Resource

Learn how our document data model can map directly to how you program your app, and native database features like secondary indexes, geospatial and text search give you full access to your data. Brought to you in partnership with MongoDB.

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. 

 

Discover when your data grows or your application performance demands increase, MongoDB Atlas allows you to scale out your deployment with an automated sharding process that ensures zero application downtime. Brought to you in partnership with MongoDB.

Topics:

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}