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
Spring Documentation for Cache Abstraction
https://docs.spring.io/spring/docs/current/spring-framework-reference/integration.html#cache
A Guide To Caching in Spring
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.