Master Spring Boot Caching with JSR‑107 and Ehcache: Step‑by‑Step Guide
Learn how to enable and configure transparent caching in Spring Boot 2.3 using JSR‑107 annotations and Ehcache, covering annotation usage, custom key generators, service and controller implementation, Maven dependencies, YAML and XML settings, and practical testing of cache put, get, and removal operations.
Environment: springboot2.3.12.RELEASE + JSR107 + Ehcache + JPA
Since Spring 3.1 the framework provides transparent caching support. From Spring 4.1 the cache abstraction supports JSR‑107 annotations and more customization.
Method 1: Using Spring annotations
Spring provides the following annotations:
@Cacheable – triggers caching
@CacheEvict – triggers cache eviction
@CachePut – updates cache without affecting method execution
@Caching – combines multiple cache operations on a method
@CacheConfig – class‑level shared cache configuration
Add the dependency:
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
</code>Service method example:
<code>@Service
public class StorageService {
@Resource
private StorageRepository sr;
@Cacheable(value = {"cache_storage"}, keyGenerator = "storageKey")
public Storage getStorage(Long id) {
return sr.findById(id).get();
}
}
</code>Custom key generator:
<code>@Component("storageKey")
public class StorageKeyGenerator implements KeyGenerator {
private static final String KEY_PREFIX = "storage_";
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
for (Object param : params) {
sb.append(param);
}
return KEY_PREFIX + sb.toString();
}
}
</code>Controller example:
<code>@RestController
@RequestMapping("/storages")
public class StorageController {
@Resource
private StorageService storageService;
@GetMapping("/{id}")
public Object get(@PathVariable("id") Long id) {
return storageService.getStorage(id);
}
}
</code>First request shows SQL output; subsequent request shows no SQL, confirming cache works.
JSR‑107 annotations can also be used with Ehcache.
Method 2: Using JSR‑107 and Ehcache
Correspondence table between Spring and JSR‑107 annotations (image).
Add Maven dependencies:
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
</dependency>
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
</code>Service using JSR‑107 annotations:
<code>@Service
public class StorageService {
@Resource
private StorageRepository sr;
@Transactional
@CachePut(cacheName = "cache_storage", cacheKeyGenerator = JCacheKeyGenerator.class)
public Storage save(@CacheValue Storage storage) {
return sr.saveAndFlush(storage);
}
@CacheResult(cacheName = "cache_storage", cacheKeyGenerator = JCacheKeyGenerator.class)
public Storage getStorage(Long id) {
return sr.findById(id).get();
}
@Transactional
@CacheRemove(cacheName = "cache_storage", cacheKeyGenerator = JCacheKeyGenerator.class)
public void removeStorage(Long id) {
sr.deleteById(id);
}
@Transactional
@CachePut(cacheName = "cache_storage", cacheKeyGenerator = JCacheKeyGenerator.class)
public Storage updateStorage(@CacheValue Storage storage) {
return sr.saveAndFlush(storage);
}
}
</code>Custom JCacheKeyGenerator (code illustration).
application.yml configuration:
<code>spring:
cache:
cacheNames:
- cache_storage
ehcache:
config: classpath:ehcache.xml
</code>ehcache.xml configuration:
<code><?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="java.io.tmpdir/Tmp_EhCache"/>
<defaultCache eternal="false" maxElementsInMemory="10000"
overflowToDisk="false" diskPersistent="false"
timeToIdleSeconds="1800" timeToLiveSeconds="259200"
memoryStoreEvictionPolicy="LRU"/>
<cache name="cache_storage" eternal="false" maxElementsInMemory="5000"
overflowToDisk="false" diskPersistent="false"
timeToIdleSeconds="1800" timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
</code>Testing add, update, delete:
Add a record (console output).
Query the newly added ID shows no SQL, confirming @CachePut works.
Delete the record (image).
Subsequent query generates SQL, indicating cache was evicted.
All steps demonstrate successful caching, cache update, and eviction using Spring annotations and JSR‑107 with Ehcache.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.