Evaluate key only if necessary
Prior to this commit a @CachePut operation would fail if the key expression is invalid, but guarded with an unless condition as the former was evaluated too early. This commit makes sure that key for a put is only evaluated if the put operation is active. Note that this does not apply for @Cacheable as the key needs to be computed early to determine if a matching entry exists in the cache. See gh-22769
This commit is contained in:
committed by
Stephane Nicoll
parent
fd17df91fd
commit
806c83591c
@@ -119,6 +119,10 @@ public @interface CacheEvict {
|
||||
* <p>The SpEL expression evaluates against a dedicated context that provides the
|
||||
* following meta-data:
|
||||
* <ul>
|
||||
* <li>{@code #result} for a reference to the result of the method invocation, which
|
||||
* can only be used if {@link #beforeInvocation()} is {@code false}. For supported
|
||||
* wrappers such as {@code Optional}, {@code #result} refers to the actual object,
|
||||
* not the wrapper</li>
|
||||
* <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
|
||||
* references to the {@link java.lang.reflect.Method method}, target object, and
|
||||
* affected cache(s) respectively.</li>
|
||||
|
||||
@@ -131,6 +131,9 @@ public @interface Cacheable {
|
||||
* <p>The SpEL expression evaluates against a dedicated context that provides the
|
||||
* following meta-data:
|
||||
* <ul>
|
||||
* <li>{@code #result} for a reference to the result of the method invocation. For
|
||||
* supported wrappers such as {@code Optional}, {@code #result} refers to the actual
|
||||
* object, not the wrapper</li>
|
||||
* <li>{@code #root.method}, {@code #root.target}, and {@code #root.caches} for
|
||||
* references to the {@link java.lang.reflect.Method method}, target object, and
|
||||
* affected cache(s) respectively.</li>
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.lang.reflect.Proxy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -401,13 +402,6 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
// Check if we have a cached item matching the conditions
|
||||
Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
|
||||
|
||||
// Collect puts from any @Cacheable miss, if no cached item is found
|
||||
List<CachePutRequest> cachePutRequests = new ArrayList<>();
|
||||
if (cacheHit == null) {
|
||||
collectPutRequests(contexts.get(CacheableOperation.class),
|
||||
CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
|
||||
}
|
||||
|
||||
Object cacheValue;
|
||||
Object returnValue;
|
||||
|
||||
@@ -422,6 +416,12 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
cacheValue = unwrapReturnValue(returnValue);
|
||||
}
|
||||
|
||||
// Collect puts from any @Cacheable miss, if no cached item is found
|
||||
List<CachePutRequest> cachePutRequests = new LinkedList<>();
|
||||
if (cacheHit == null) {
|
||||
collectPutRequests(contexts.get(CacheableOperation.class), cacheValue, cachePutRequests);
|
||||
}
|
||||
|
||||
// Collect any explicit @CachePuts
|
||||
collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);
|
||||
|
||||
@@ -558,7 +558,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
@Nullable Object result, Collection<CachePutRequest> putRequests) {
|
||||
|
||||
for (CacheOperationContext context : contexts) {
|
||||
if (isConditionPassing(context, result)) {
|
||||
if (isConditionPassing(context, result) && context.canPutToCache(result)) {
|
||||
Object key = generateKey(context, result);
|
||||
putRequests.add(new CachePutRequest(context, key));
|
||||
}
|
||||
@@ -832,10 +832,8 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
|
||||
}
|
||||
|
||||
public void apply(@Nullable Object result) {
|
||||
if (this.context.canPutToCache(result)) {
|
||||
for (Cache cache : this.context.getCaches()) {
|
||||
doPut(cache, this.key, result);
|
||||
}
|
||||
for (Cache cache : this.context.getCaches()) {
|
||||
doPut(cache, this.key, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user