Custom Cache Key in Spring Boot: Using SpEL for Fine-Grained Caching
Caching is a powerful technique to boost performance in Spring Boot applications, but its effectiveness depends heavily on how cache keys are generated. By default, Spring uses method parameters to create cache keys, which may not always be optimal for your use case. Customizing cache keys using Spring Expression Language (SpEL) lets you fine-tune cache granularity, avoid collisions, and minimize memory use—all with minimal code changes.
Why Customize Cache Keys?
- Avoid Collisions: Default keys may cause different requests to map to the same cache entry if method signatures overlap.
- Optimize Memory: Large or complex objects as keys can waste heap space; custom keys can be concise and targeted.
- Control Granularity: Fine-tune what constitutes a unique cache entry, e.g., by combining only certain fields or parameters.
How Spring Boot Handles Cache Keys
Spring Boot’s caching abstraction (via @Cacheable
, @CachePut
, and @CacheEvict
) uses the SimpleKeyGenerator
by default. This generator creates keys based on all method arguments, or just the argument itself if only one is present. For more control, you can:
- Use the
key
attribute with a SpEL expression. - Implement a custom
KeyGenerator
bean.
Custom Cache Key with SpEL: The Practical Approach
The simplest and most powerful way to customize cache keys is by using SpEL in the key
attribute of caching annotations.
Example: Caching with a Custom Key Using SpEL
Suppose you have a service method that fetches reservations for a restaurant:
@Cacheable(value = "reservationsCache", key = "#restaurant.id")
public List<Reservation> getReservationsForRestaurant(Restaurant restaurant) {
// fetch reservations
}
In this example, only the restaurant’s unique id
property is used as the cache key, rather than the whole Restaurant
object. This makes the cache more efficient and avoids unnecessary memory usage.
Advanced SpEL Example
You can build more complex keys by combining multiple fields and static text:
@CachePut(
value = "products",
key = "T(java.lang.String).format('%s-%s-%s', #root.target.class.simpleName, #root.method.name, #product.name)"
)
public Product save(Product product) {
// save product logic
}
Here, the cache key is a formatted string combining the class name, method name, and product name. For a product named "Hello Koding", the key would be "ProductService-save-Hello Koding"
.
SpEL Reference Points
#paramName
: Refers to a method parameter by name.#root.methodName
: The method’s name.#root.target
: The target object.T(type)
: Reference a Java type for static methods.
When to Use a Custom KeyGenerator
If SpEL expressions become unwieldy or you need logic that can’t be expressed in SpEL, implement a custom KeyGenerator
:
@Component("customKeyGenerator")
public class CustomKeyGenerator implements KeyGenerator {
@Override
public Object generate(Object target, Method method, Object... params) {
return method.getName() + "_" + Arrays.toString(params);
}
}
Then, reference it in your annotation:
@Cacheable(value = "users", keyGenerator = "customKeyGenerator")
public User getUserById(Long id) {
// fetch user logic
}
This approach is ideal for complex key logic, such as combining multiple parameters, including user context, or applying hashing.
Best Practices
- Keep Keys Small: Use only necessary fields or IDs to minimize memory use.
- Ensure Uniqueness: Combine fields that uniquely identify the cached data.
- Document Key Logic: Make key generation logic clear for maintainability.
Conclusion
Customizing cache keys in Spring Boot using SpEL is a best practice for any production application that relies heavily on caching. It improves cache hit rates, reduces memory waste, and gives you full control over cache granularity. For most cases, SpEL in the key
attribute is sufficient; for advanced needs, implement a custom KeyGenerator
bean.
By mastering custom cache keys, you ensure your Spring Boot application is both fast and resource-efficient.
References: DZone: Spring Cache Annotation Tips and Tricks HelloKoding: Spring Cache Key Generator Reflectoring: Implementing a Cache with Spring Boot BestDivision: How do you implement a custom cache key generator in Spring?