Cache Abstraction (Spring Boot)

Introduction

The caching abstraction allows consistent use of various caching solutions with minimal impact on the code.

Any method calls response can be cached using this abstraction, with the method parameters as the keys and the return type as the response.

Spring Boot supports JSR-107 annotations and customization options.


Note: This cache abstraction can be backed by simple JVM caches like Guava or more sophisticated cache implementations like EHCache, Redis or HazelCast as well.


References

https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#cache

http://www.baeldung.com/spring-cache-tutorial


Configuration

Let's demonstrate step by step how to enable caching for a method that invokes a remote web service in an already existing Spring Boot application.


Enable caching

The caching feature can be declaratively enabled by simply adding the @EnableCaching annotation to any of the configuration classes.

Note: The method 'evictCache4h' is a hack for invalidating this basic cache every 4 hours (if using a sophisticated cache manager, use its configuration instead).

/**

 * 

 * "@EnableCaching" enables spring caching for annotation "@Cacheable", etc.

 * (remove this annotation if issues with cache arise).

 *

 */

@EnableCaching

@Configuration

public class CachingConfig implements CachingConfigurer

   /*(sb<3 extends CachingConfigurerSupport*/ {


  /** Cache for responses from WS */

 public static final String EXTENDED_CONTEXT_RESPONSE_DTO = "EXTENDED_CONTEXT_RESPONSE_DTO";


 @Bean

 public CacheManager cacheManager() {

  return new ConcurrentMapCacheManager(EXTENDED_CONTEXT_RESPONSE_DTO);

 }


 /**

  * Evict caches:<br>

  * -EXTENDED_CONTEXT_RESPONSE_DTO: Every 4 hours<br>

  */

 @CacheEvict(allEntries = true, value = { EXTENDED_CONTEXT_RESPONSE_DTO })

 @Scheduled(fixedDelay = 2 * 60 * 60 * 1000, initialDelay = 2 * 60 * 60 * 1000)

 public void evictCache4h() {

  SimpleDateFormat dt = new SimpleDateFormat("yyyyy-mm-dd hh:mm:ss");

  System.out.println("Flush Cache " + EXTENDED_CONTEXT_RESPONSE_DTO + " " + dt.format(new Date()));

 }


}


@Cacheable

The simplest way to enable caching behavior for a method is to demarcate it with @Cacheable and parameterize it with the name of the cache where the results would be stored:

 @Cacheable(CachingConfig.EXTENDED_CONTEXT_RESPONSE_DTO)

 @Override

 public ExtendedContextResponseDTO getExtendedUser(String module, String id)

   throws RemoteInterfaceException, SocketTimeoutException {

         //Method body scrapped

}


@CachePut

@CachePut always lets the method execute. It is generally used if you want your cache to be updated with the result of the method execution.

Example: When you want to update a stale data which is cached, instead of blowing the cache completely.

@Cacheable will be executed only once for the given cachekey and subsequent requests won't execute the method, until the cache expires or gets flushed.