This method-level annotation lets Spring Boot know that the return value of the annotated method can be cached. Each time a method marked with this @Cacheable is called, the caching behavior will be applied. In particular, Spring Boot will check whether the method has been already invoked for the given arguments. This involves looking for a key, which is generated using the method parameters by default. If no value is found in the cache related to the method for the computed key, the target method will be executed normally. Otherwise, the cached value will be returned immediately.
@Cacheable
comes with many parameters, but the simplest way to use it is to annotate a method with the annotation and parameterize it with the name of the cache where the results are going to be stored.
@Cacheable("authors")
public List<Author> getAuthors(List<Int> ids) { ... }
You can also specify how the key that uniquely identifies each entry in the cache should be generated by harnessing the key attribute.
@Cacheable(value="book", key="#isbn")
public Book findBookByISBN(String isbn) { ... }
@Cacheable(value="books", key="#author.id")
public Books findBooksByAuthor(Author author) { ... }
Lastly, it is also possible to enable conditional caching as in the following example:
// caching only authors whose full name is less than 15 carachters
@Cacheable(value="authors", condition="#fullName.length < 15")
public Authors findAuthorsByFullName(String fullName) { ... }
This method-level annotation should be used when you want to update (put) the cache without avoiding the method from being executed. This means that the method will always be executed — according to the @CachePut
options — and its result will be stored in the cache.
The main difference between @Cacheable
and @CachePut
is that the first might avoid executing the method, while the second will run the method and put its results in the cache, even if there is already an existing key associated with the given parameters. Since they have different behaviors, annotating the same method with both @CachePut
and @Cacheable
should be avoided.
This method-level annotation allows you to remove (evict) data previously stored in the cache. By annotating a method with @CacheEvict
you can specify the removal of one or all values so that fresh values can be loaded into the cache again. If you want to remove a specific value, you should pass the cache key as an argument to the annotation, as in the following example:
@CacheEvict(value="authors", key="#authorId")
public void evictSingleAuthor(Int authorId) { ... }
While if you want to clear an entire cache you can the parameter allEntries in conjunction with the name of cache to be cleared:
@CacheEvict(value="authors", allEntries=true)
public String evictAllAuthorsCached() { ... }
@CacheEvict
is extremely important because size is the main problem of caches.
A possible solution to this problem is to compress data before caching, as explained here. On the other hand, the best approach should be to avoid keeping data that you are not using too often in the caches. In fact, since caches can become large very quickly, you should update stale data with @CachePut and remove unused data with @CacheEvict
.`
In particular, having a method to clean all the caches of your Spring Boot application easily can become essential. It can be called in type of method like this :
- when the data changes
- When you want to periodically empty the cache
This class-level annotation allows you to specify some of the cache configurations in one place, so you do not have to repeat them multiple times:
@CacheConfig(cacheNames={"authors"})
public class AuthorDAO {
@Cacheable
publicList<Author> findAuthorsByFullName(String fullName) { ... }
@Cacheable
public List<Author> findAuthorsByBook(Book book) { ... }
// ...
}
reference