Unravel โบ Java concepts โบ Spring and Boot
Spring caching
@Cacheable stores a method's result under a key built from its arguments.
Learn these first
At a glance
A notebook of answers you have already worked out.
- 1@EnableCaching switches the feature onA method annotated @Cacheable("customers") is wrapped by a proxy: it builds a key from the arguments, looks it up in the named cache, and only calls the real method on a miss, storing the result.
- 2@CacheEvict removes entries when data changes, and @CachePut always runs the method and updates the entry
- 3The cache itself comes from a CacheManagerThe default is a simple in-memory map; for real use pick Caffeine (local, with size limits and expiry) or Redis (shared between instances).
- 4Because it works through a proxy, a call from inside the same class bypasses the cache, and private methods are never cached
- Every cache needs an answer to "when is this wrong?"
- The key is built from all arguments by default, so passing a large or mutable object as an argument makes poor keys
- A CacheInterceptor in the proxy chain computes the key with a KeyGenerator (or a SpEL expression), reads and writes the Cache, and handles sync = true to stop many threads computing the same missing value at once (the cache stampede)
@Servicepublic class CustomerService { @Cacheable(value = "customers", key = "#id", unless = "#result == null") public Customer find(long id) { return repository.findById(id).orElse(null); } @CacheEvict(value = "customers", key = "#customer.id") public void update(Customer customer) { repository.save(customer); }}- line 3 uses Cacheable, the core of Spring caching
- line 8 uses CacheEvict, the core of Spring caching
Read the full explanation (about 2 min)
@Cacheable stores a method's result under a key built from its arguments. The next call with the same arguments returns the stored result and skips the method body, trading memory and freshness for speed.
A mental model
A notebook of answers you have already worked out. Before doing a long calculation you look in the notebook; if the answer is there you read it out. The risk is that the notebook is out of date.
How it works
@EnableCaching switches the feature on. A method annotated @Cacheable("customers") is wrapped by a proxy: it builds a key from the arguments, looks it up in the named cache, and only calls the real method on a miss, storing the result.
@CacheEvict removes entries when data changes, and @CachePut always runs the method and updates the entry.
The cache itself comes from a CacheManager. The default is a simple in-memory map; for real use pick Caffeine (local, with size limits and expiry) or Redis (shared between instances).
Because it works through a proxy, a call from inside the same class bypasses the cache, and private methods are never cached.
Going deeper
Every cache needs an answer to "when is this wrong?". Without an expiry or eviction rule, the cache returns stale data until the process restarts. Set a time to live and evict on writes.
The key is built from all arguments by default, so passing a large or mutable object as an argument makes poor keys. Use key = "#id" to choose explicitly.
Null results are cached too unless you say unless = "#result == null", which can hide a record that is created a moment later.
With several application instances a local cache is per instance: an eviction on one node does not clear the others. Use a shared cache or short expiry when that matters.
Under the hood
A CacheInterceptor in the proxy chain computes the key with a KeyGenerator (or a SpEL expression), reads and writes the Cache, and handles sync = true to stop many threads computing the same missing value at once (the cache stampede).
Common mistakes
- No expiry, so data goes stale for ever.
- Calling a cached method from the same class.
- Caching results that depend on the current user without including the user in the key.
- Caching null or error results by accident.
How Unravel recognises it
When you paste code, Unravel looks for these signs of spring caching. Spotting them yourself is a good habit when you read unfamiliar code:
- Annotations:
@Cacheable@CacheEvict@CachePut@Caching@EnableCaching@CacheConfig - Types:
CacheManagerCacheCaffeineConcurrentMapCacheManager
Part of a learning path
Related concepts
Frequently asked questions
What is Spring caching?
@Cacheable stores a method's result under a key built from its arguments. The next call with the same arguments returns the stored result and skips the method body, trading memory and freshness for speed.
What are the most common mistakes with Spring caching?
No expiry, so data goes stale for ever. Calling a cached method from the same class. Caching results that depend on the current user without including the user in the key. Caching null or error results by accident.
How can I see Spring caching in real code?
Paste your own Java into Unravel and it will point out where spring caching appears, explain how it works at the detail level you choose, and draw the flow of the code around it.