Currently, it's expected from the user to provide their own CacheResolver
if they wish to use SpEL inside @Cache*(cacheNames="...")
. I think it wouldn't hurt if it was implemented out of the box as templated expressions:
"myCache-#{#arg}-#{@bean.something()}" etc.
Especially given the fact that CacheOperationExpressionEvaluator
is already implemented for key
, unless
, and condition
attributes of @Cache*
annotations.
And it will behave exactly the same as it does now but also can evaluate a templated expression if there is one:
if (!expression.contains(templateParserContext.getExpressionPrefix())) return expression;
I decided to put that stuff right into SimpleCacheResolver
making its factory methods backward-compatible. I don't see a point in creating a second resolver class because it still does the same thing if there's no nested expression in the name, and there's effectively no penalty in simply checking String#contains
every time.
Example usecase:
@Cacheable(cacheNames = "schemas-#{#vendorId}", key = "#entityId")
public Schema getSchema(String vendorId, String entityId){...}
@CacheEvict(cacheNames = "schemas-#{#vendorId}", allEntries = true)
public void updateVendor(String vendorId, VendorDto newData){...}
Here, if I don't have SpEL inside cache names, I can only define a cache named "schemas", but whenever I want to update one vendor, I only want its cache to be evicted, not everyone's. An alternative is to manage the cache programmatically or implement my own cache resolver.
Comment From: snicoll
@Sam-Kruglov thank you for the PR but we're not keen to extend the support and rather recommend to use CacheResolver
.