Master Spring Boot 3 Caching: 8 Powerful Techniques & Real-World Examples
This article walks through eight practical Spring Boot 3 caching techniques—including @Cacheable, @CacheEvict, custom key generators, multi‑level caches, TTL, conditional caching, and async refresh—providing code snippets and diagrams to help developers boost application performance.
Introduction
Spring Boot's annotation‑driven cache mechanism can dramatically improve performance. This article presents eight practical caching techniques, covering common annotations, multi‑level caches, TTL, conditional caching, and asynchronous refresh.
1. @Cacheable
Cache the result of a method. Example:
@Cacheable(key = "#user.id", cacheNames = {"users"})
public User save(User user) {
return user;
}The key combines the prefix "users" with the user’s id and can be stored in Caffeine or Redis.
2. @CacheConfig
Define common cache settings at class level.
@Service
@CacheConfig(cacheNames = {"users"})
public class UserService {
@Cacheable(key = "#user.id")
public User save(User user) {
return user;
}
}3. @CacheEvict
Remove entries from the cache.
@CacheEvict(cacheNames = "users", key = "#id")
public void deleteById(Long id) {
System.out.printf("Deleted user [%d]%n", id);
}To clear all entries:
@CacheEvict(cacheNames = "users", allEntries = true)
public void deleteAll() { }4. @CachePut
Update the cache after method execution.
@CachePut(key = "#user.id")
public User updateUser(User user) {
return user;
}Difference from @Cacheable: @Cacheable skips method execution when the key exists, while @CachePut always runs and writes the result.
5. Custom Key Generation
Implement a KeyGenerator bean to produce complex keys.
@Bean
KeyGenerator packKeyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
return target.getClass().getSimpleName() + "@" + method.getName()
+ "@" + Arrays.deepToString(params);
}
};
}Use it with:
@Cacheable(keyGenerator = "packKeyGenerator")
public User save(User user) { ... }6. Multi‑Level Cache
Combine fast in‑memory caches (Caffeine, EhCache) with Redis for scalability.
Check memory cache first.
If miss, fall back to Redis.
Only query the database when both caches miss.
Libraries such as Spring Cache abstraction + Caffeine + Redis or JetCache can implement this pattern.
7. Cache TTL (Time‑to‑Live)
Configure expiration to avoid stale data. Example for Redis:
spring:
cache:
type: redis
redis:
time-to-live: 60s8. Conditional Caching
Cache only when a condition is met.
@Cacheable(keyGenerator = "packKeyGenerator", condition = "#user.id != 666")
public User save(User user) { ... }Or skip caching when the result is null:
@Cacheable(unless = "#result == null")
public User save(User user) { ... }9. Asynchronous Cache Refresh
Refresh cache periodically instead of waiting for a miss.
@Scheduled(fixedRate = 3600000)
public void refreshDictCache() {
List<Dict> dicts = dictRepository.findAll();
dicts.forEach(d -> cacheManager.getCache("dicts").put(d.getId(), d));
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
