{{announcement.body}}
{{announcement.title}}

Spring Boot With Ehcache 3 and JSR-107

DZone 's Guide to

Spring Boot With Ehcache 3 and JSR-107

Bring caching to your Spring Boot apps! To help, we'll use Ehcache 3 and the always-helpful JCache annotations.

· Java Zone ·
Free Resource

Here we are going to cover how to use Ehcache 3 for caching in Spring Boot based on JSR-107. We will tackle how to do operations on the cache itself (besides the well-known annotation usage).

Before we start, let's highlight JSR-107.

JSR-107(JCache) Annotations

In regards to caching, Spring offers support for two sets of annotations that can be used to implement caching. You have the original Spring annotations and the JSR-107 annotations.

Steps to Use Ehcache 3 With Spring Boot

Create a Spring Boot Maven project and add the following Maven dependencies in your pom.xml, along with Spring Boot dependencies:

<!-- ehcache and JSR dependencies--> 
<dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>${ehcache}</version>
</dependency>
 <dependency>
            <groupId>javax.cache</groupId>
            <artifactId>cache-api</artifactId>
</dependency>
<!-- spring boot cache starter--> 
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
</dependency>


Set the spring.cache.jcache.config property to include the classpath and ehcache.xml file. Enable the following in your application.yml file:

Screen Shot 2017-12-22 at 15.55.12.png

Enable caching in the Spring Boot main class:

@SpringBootApplication
//enable Spring Boot caching
@EnableCaching
public class AlertManagerApplication {
    public static void main(String[] args) {
        SpringApplication.run(AlertManagerApplication.class, args);
    }
}


Configure your Ehcache XML file as follows:

<config
        xmlns:jsr107='http://www.ehcache.org/v3/jsr107'
        xmlns='http://www.ehcache.org/v3'>
    <service>
        <jsr107:defaults enable-management="true" enable-statistics="true"/>
    </service>
    <!-- file persistance enabling--> 
    <persistence directory="./cache"></persistence>
    <!-- the 2 caches we will create-->
    <cache alias="AlertsConfig" uses-template="config-cache"/>
    <cache alias="Alerts" uses-template="alerts-template"/>
      <!-- the config cache tenplate-->
    <cache-template name="config-cache">
        <listeners>
            <listener>
                 <!-- the the main cache event listener-->
                <class>com.demo.alertmanager.services.CacheEventLogger</class>
                <event-firing-mode>ASYNCHRONOUS</event-firing-mode>
                <event-ordering-mode>UNORDERED</event-ordering-mode>
                <events-to-fire-on>CREATED</events-to-fire-on>
                <events-to-fire-on>UPDATED</events-to-fire-on>
                <events-to-fire-on>EXPIRED</events-to-fire-on>
                <events-to-fire-on>REMOVED</events-to-fire-on>
                <events-to-fire-on>EVICTED</events-to-fire-on>
            </listener>
        </listeners>
        <resources>
            <heap>1</heap>
            <offheap unit="MB">1</offheap>
            <disk persistent="true" unit="MB">100</disk>
        </resources>
    </cache-template>

    <cache-template name="alerts-template">
        <listeners>
            <listener>
                <class>com.demo.alertmanager.services.CacheEventLogger</class>
                <event-firing-mode>ASYNCHRONOUS</event-firing-mode>
                <event-ordering-mode>UNORDERED</event-ordering-mode>
                <events-to-fire-on>CREATED</events-to-fire-on>
                <events-to-fire-on>UPDATED</events-to-fire-on>
                <events-to-fire-on>EXPIRED</events-to-fire-on>
                <events-to-fire-on>REMOVED</events-to-fire-on>
                <events-to-fire-on>EVICTED</events-to-fire-on>
            </listener>
        </listeners>
        <resources>
          <heap>1</heap>
            <offheap unit="MB">1</offheap>
            <disk persistent="true" unit="MB">100</disk>
        </resources>
    </cache-template>

</config>


For more information about the XML configuration, please check the following: 

Then you can easily inject the cache manager in your bean class.

@Autowired
//inject the cache manager
private javax.cache.CacheManager cacheManager;

//get access to your cache for further operations by cache name
private Cache < String, List < AlertEntry >> getAlertsCache() {
    return cacheManager.getCache(CacheNames.Alerts.name());
}
//close the cache manager upon bean destruction for proper cache file persistence 
@PreDestroy
public void close() {
    cacheManager.close();
}


Start accessing your caches from the cache manager. If you want to do direct operations over it like below, please check EhcacheAlertsStore.java in the GitHub project for more details.

@Override
// if you want to do atomic updates over the cache entry
public void updateAlertEntry(String serviceId, String serviceCode, AlertEntry alertEntry) {
    //get the JSR cache reference 
    final Cache < String, List < AlertEntry >> alertsCache = getAlertsCache();
    //then invoke atomic updates on the cache entry 
    alertsCache.invoke(serviceId, (mutableEntry, objects) - > {
        if (mutableEntry.exists() && mutableEntry.getValue() != null) {
            logger.debug("updating alert entry into the cache store invoke: {},{}", serviceId, serviceCode);
            final List < AlertEntry > alertEntries = mutableEntry.getValue();
            // remove only if it has the error code
            alertEntries.removeIf(alertEntry1 - > alertEntry1.getErrorCode().equals(serviceCode));
            alertEntries.add(alertEntry);
            mutableEntry.setValue(alertEntries);
        } else {
            throw new ResourceNotFoundException(String.format("Alert for %s with %s not found", serviceId, serviceCode));
        }
        //by the API design, nothing is needed here
        return null;
    });
}


The complete code sample for testing is on GitHub, where you can run it and play with REST APIs for cache operations via the generated runtime Swagger.

References

Topics:
ehcache ,caching ,spring boot ,java ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}