Skip to content

Commit 9645799

Browse files
committed
Fixed accidental use of JDK 8 getOrDefault method on MultiValueMap
Issue: SPR-10807
1 parent 2626a35 commit 9645799

File tree

1 file changed

+85
-96
lines changed

1 file changed

+85
-96
lines changed

spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java

Lines changed: 85 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import org.apache.commons.logging.Log;
2727
import org.apache.commons.logging.LogFactory;
28+
2829
import org.springframework.aop.framework.AopProxyUtils;
2930
import org.springframework.beans.factory.InitializingBean;
3031
import org.springframework.cache.Cache;
@@ -67,19 +68,65 @@ public abstract class CacheAspectSupport implements InitializingBean {
6768

6869
protected final Log logger = LogFactory.getLog(getClass());
6970

71+
private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
7072

7173
private CacheManager cacheManager;
7274

7375
private CacheOperationSource cacheOperationSource;
7476

75-
private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
76-
7777
private KeyGenerator keyGenerator = new SimpleKeyGenerator();
7878

7979
private boolean initialized = false;
8080

8181

82-
@Override
82+
/**
83+
* Set the CacheManager that this cache aspect should delegate to.
84+
*/
85+
public void setCacheManager(CacheManager cacheManager) {
86+
this.cacheManager = cacheManager;
87+
}
88+
89+
/**
90+
* Return the CacheManager that this cache aspect delegates to.
91+
*/
92+
public CacheManager getCacheManager() {
93+
return this.cacheManager;
94+
}
95+
96+
/**
97+
* Set one or more cache operation sources which are used to find the cache
98+
* attributes. If more than one source is provided, they will be aggregated using a
99+
* {@link CompositeCacheOperationSource}.
100+
* @param cacheOperationSources must not be {@code null}
101+
*/
102+
public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) {
103+
Assert.notEmpty(cacheOperationSources);
104+
this.cacheOperationSource = (cacheOperationSources.length > 1 ?
105+
new CompositeCacheOperationSource(cacheOperationSources) : cacheOperationSources[0]);
106+
}
107+
108+
/**
109+
* Return the CacheOperationSource for this cache aspect.
110+
*/
111+
public CacheOperationSource getCacheOperationSource() {
112+
return this.cacheOperationSource;
113+
}
114+
115+
/**
116+
* Set the KeyGenerator for this cache aspect.
117+
* Default is {@link DefaultKeyGenerator}.
118+
*/
119+
public void setKeyGenerator(KeyGenerator keyGenerator) {
120+
this.keyGenerator = keyGenerator;
121+
}
122+
123+
/**
124+
* Return the KeyGenerator for this cache aspect,
125+
*/
126+
public KeyGenerator getKeyGenerator() {
127+
return this.keyGenerator;
128+
}
129+
83130
public void afterPropertiesSet() {
84131
Assert.state(this.cacheManager != null, "'cacheManager' is required");
85132
Assert.state(this.cacheOperationSource != null, "The 'cacheOperationSources' "
@@ -88,6 +135,7 @@ public void afterPropertiesSet() {
88135
this.initialized = true;
89136
}
90137

138+
91139
/**
92140
* Convenience method to return a String representation of this Method
93141
* for use in logging. Can be overridden in subclasses to provide a
@@ -113,22 +161,20 @@ protected Collection<Cache> getCaches(CacheOperation operation) {
113161
return caches;
114162
}
115163

116-
protected CacheOperationContext getOperationContext(CacheOperation operation,
117-
Method method, Object[] args, Object target, Class<?> targetClass) {
164+
protected CacheOperationContext getOperationContext(CacheOperation operation, Method method, Object[] args,
165+
Object target, Class<?> targetClass) {
166+
118167
return new CacheOperationContext(operation, method, args, target, targetClass);
119168
}
120169

121170
protected Object execute(Invoker invoker, Object target, Method method, Object[] args) {
122-
123171
// check whether aspect is enabled
124172
// to cope with cases where the AJ is pulled in automatically
125173
if (this.initialized) {
126174
Class<?> targetClass = getTargetClass(target);
127-
Collection<CacheOperation> operations = getCacheOperationSource().
128-
getCacheOperations(method, targetClass);
175+
Collection<CacheOperation> operations = getCacheOperationSource().getCacheOperations(method, targetClass);
129176
if (!CollectionUtils.isEmpty(operations)) {
130-
return execute(invoker, new CacheOperationContexts(operations,
131-
method, args, target, targetClass));
177+
return execute(invoker, new CacheOperationContexts(operations, method, args, target, targetClass));
132178
}
133179
}
134180

@@ -144,30 +190,27 @@ private Class<?> getTargetClass(Object target) {
144190
}
145191

146192
private Object execute(Invoker invoker, CacheOperationContexts contexts) {
147-
148193
// Process any early evictions
149194
processCacheEvicts(contexts.get(CacheEvictOperation.class), true, ExpressionEvaluator.NO_RESULT);
150195

151196
// Collect puts from any @Cachable miss
152197
List<CachePutRequest> cachePutRequests = new ArrayList<CachePutRequest>();
153-
collectPutRequests(contexts.get(CacheableOperation.class),
154-
ExpressionEvaluator.NO_RESULT, cachePutRequests, true);
198+
collectPutRequests(contexts.get(CacheableOperation.class), ExpressionEvaluator.NO_RESULT, cachePutRequests, true);
155199

156200
ValueWrapper result = null;
157201

158202
// We only attempt to get a cached result if there are no put requests
159-
if(cachePutRequests.isEmpty() && contexts.get(CachePutOperation.class).isEmpty()) {
203+
if (cachePutRequests.isEmpty() && contexts.get(CachePutOperation.class).isEmpty()) {
160204
result = findCachedResult(contexts.get(CacheableOperation.class));
161205
}
162206

163207
// Invoke the method if don't have a cache hit
164-
if(result == null) {
208+
if (result == null) {
165209
result = new SimpleValueWrapper(invoker.invoke());
166210
}
167211

168212
// Collect any explicit @CachePuts
169-
collectPutRequests(contexts.get(CachePutOperation.class), result.get(),
170-
cachePutRequests, false);
213+
collectPutRequests(contexts.get(CachePutOperation.class), result.get(), cachePutRequests, false);
171214

172215
// Process any collected put requests, either from @CachePut or a @Cacheable miss
173216
for (CachePutRequest cachePutRequest : cachePutRequests) {
@@ -180,26 +223,24 @@ private Object execute(Invoker invoker, CacheOperationContexts contexts) {
180223
return result.get();
181224
}
182225

183-
private void processCacheEvicts(Collection<CacheOperationContext> contexts,
184-
boolean beforeInvocation, Object result) {
226+
private void processCacheEvicts(Collection<CacheOperationContext> contexts, boolean beforeInvocation, Object result) {
185227
for (CacheOperationContext context : contexts) {
186228
CacheEvictOperation operation = (CacheEvictOperation) context.operation;
187-
if (beforeInvocation == operation.isBeforeInvocation() &&
188-
isConditionPassing(context, result)) {
229+
if (beforeInvocation == operation.isBeforeInvocation() && isConditionPassing(context, result)) {
189230
performCacheEvict(context, operation, result);
190231
}
191232
}
192233
}
193234

194-
private void performCacheEvict(CacheOperationContext context,
195-
CacheEvictOperation operation, Object result) {
235+
private void performCacheEvict(CacheOperationContext context, CacheEvictOperation operation, Object result) {
196236
Object key = null;
197237
for (Cache cache : context.getCaches()) {
198238
if (operation.isCacheWide()) {
199239
logInvalidating(context, operation, null);
200240
cache.clear();
201-
} else {
202-
if(key == null) {
241+
}
242+
else {
243+
if (key == null) {
203244
key = context.generateKey(result);
204245
}
205246
logInvalidating(context, operation, key);
@@ -211,14 +252,14 @@ private void performCacheEvict(CacheOperationContext context,
211252
private void logInvalidating(CacheOperationContext context,
212253
CacheEvictOperation operation, Object key) {
213254
if (this.logger.isTraceEnabled()) {
214-
this.logger.trace("Invalidating " +
215-
(key == null ? "entire cache" : "cache key " + key) +
255+
this.logger.trace("Invalidating " + (key == null ? "entire cache" : "cache key " + key) +
216256
" for operation " + operation + " on method " + context.method);
217257
}
218258
}
219259

220260
private void collectPutRequests(Collection<CacheOperationContext> contexts,
221261
Object result, Collection<CachePutRequest> putRequests, boolean whenNotInCache) {
262+
222263
for (CacheOperationContext context : contexts) {
223264
if (isConditionPassing(context, result)) {
224265
Object key = generateKey(context, result);
@@ -233,9 +274,8 @@ private Cache.ValueWrapper findCachedResult(Collection<CacheOperationContext> co
233274
ValueWrapper result = null;
234275
for (CacheOperationContext context : contexts) {
235276
if (isConditionPassing(context, ExpressionEvaluator.NO_RESULT)) {
236-
if(result == null) {
237-
result = findInCaches(context,
238-
generateKey(context, ExpressionEvaluator.NO_RESULT));
277+
if (result == null) {
278+
result = findInCaches(context, generateKey(context, ExpressionEvaluator.NO_RESULT));
239279
}
240280
}
241281
}
@@ -254,76 +294,25 @@ private Cache.ValueWrapper findInCaches(CacheOperationContext context, Object ke
254294

255295
private boolean isConditionPassing(CacheOperationContext context, Object result) {
256296
boolean passing = context.isConditionPassing(result);
257-
if(!passing && this.logger.isTraceEnabled()) {
297+
if (!passing && this.logger.isTraceEnabled()) {
258298
this.logger.trace("Cache condition failed on method " + context.method + " for operation " + context.operation);
259299
}
260300
return passing;
261301
}
262302

263303
private Object generateKey(CacheOperationContext context, Object result) {
264304
Object key = context.generateKey(result);
265-
Assert.notNull(key, "Null key returned for cache operation (maybe you "
266-
+ "are using named params on classes without debug info?) "
267-
+ context.operation);
305+
Assert.notNull(key, "Null key returned for cache operation (maybe you are using named params " +
306+
"on classes without debug info?) " + context.operation);
268307
if (this.logger.isTraceEnabled()) {
269308
this.logger.trace("Computed cache key " + key + " for operation " + context.operation);
270309
}
271310
return key;
272311
}
273312

274313

275-
/**
276-
* Set the CacheManager that this cache aspect should delegate to.
277-
*/
278-
public void setCacheManager(CacheManager cacheManager) {
279-
this.cacheManager = cacheManager;
280-
}
281-
282-
/**
283-
* Return the CacheManager that this cache aspect delegates to.
284-
*/
285-
public CacheManager getCacheManager() {
286-
return this.cacheManager;
287-
}
288-
289-
/**
290-
* Set one or more cache operation sources which are used to find the cache
291-
* attributes. If more than one source is provided, they will be aggregated using a
292-
* {@link CompositeCacheOperationSource}.
293-
* @param cacheOperationSources must not be {@code null}
294-
*/
295-
public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) {
296-
Assert.notEmpty(cacheOperationSources);
297-
this.cacheOperationSource =
298-
(cacheOperationSources.length > 1 ?
299-
new CompositeCacheOperationSource(cacheOperationSources) :
300-
cacheOperationSources[0]);
301-
}
302-
303-
/**
304-
* Return the CacheOperationSource for this cache aspect.
305-
*/
306-
public CacheOperationSource getCacheOperationSource() {
307-
return this.cacheOperationSource;
308-
}
309-
310-
/**
311-
* Set the KeyGenerator for this cache aspect.
312-
* Default is {@link SimpleKeyGenerator}.
313-
*/
314-
public void setKeyGenerator(KeyGenerator keyGenerator) {
315-
this.keyGenerator = keyGenerator;
316-
}
317-
318-
/**
319-
* Return the KeyGenerator for this cache aspect,
320-
*/
321-
public KeyGenerator getKeyGenerator() {
322-
return this.keyGenerator;
323-
}
324-
325-
326314
public interface Invoker {
315+
327316
Object invoke();
328317
}
329318

@@ -335,14 +324,16 @@ private class CacheOperationContexts {
335324

336325
public CacheOperationContexts(Collection<? extends CacheOperation> operations,
337326
Method method, Object[] args, Object target, Class<?> targetClass) {
327+
338328
for (CacheOperation operation : operations) {
339329
this.contexts.add(operation.getClass(), new CacheOperationContext(operation,
340330
method, args, target, targetClass));
341331
}
342332
}
343333

344334
public Collection<CacheOperationContext> get(Class<? extends CacheOperation> operationClass) {
345-
return this.contexts.getOrDefault(operationClass, Collections.<CacheOperationContext> emptyList());
335+
Collection<CacheOperationContext> result = this.contexts.get(operationClass);
336+
return (result != null ? result : Collections.<CacheOperationContext> emptyList());
346337
}
347338
}
348339

@@ -361,7 +352,6 @@ protected class CacheOperationContext {
361352

362353
private final Collection<Cache> caches;
363354

364-
365355
public CacheOperationContext(CacheOperation operation, Method method, Object[] args, Object target, Class<?> targetClass) {
366356
this.operation = operation;
367357
this.method = method;
@@ -374,8 +364,7 @@ public CacheOperationContext(CacheOperation operation, Method method, Object[] a
374364
protected boolean isConditionPassing(Object result) {
375365
if (StringUtils.hasText(this.operation.getCondition())) {
376366
EvaluationContext evaluationContext = createEvaluationContext(result);
377-
return CacheAspectSupport.this.evaluator.condition(this.operation.getCondition(), this.method,
378-
evaluationContext);
367+
return evaluator.condition(this.operation.getCondition(), this.method, evaluationContext);
379368
}
380369
return true;
381370
}
@@ -388,9 +377,9 @@ protected boolean canPutToCache(Object value) {
388377
else if (this.operation instanceof CachePutOperation) {
389378
unless = ((CachePutOperation) this.operation).getUnless();
390379
}
391-
if(StringUtils.hasText(unless)) {
380+
if (StringUtils.hasText(unless)) {
392381
EvaluationContext evaluationContext = createEvaluationContext(value);
393-
return !CacheAspectSupport.this.evaluator.unless(unless, this.method, evaluationContext);
382+
return !evaluator.unless(unless, this.method, evaluationContext);
394383
}
395384
return true;
396385
}
@@ -402,14 +391,13 @@ else if (this.operation instanceof CachePutOperation) {
402391
protected Object generateKey(Object result) {
403392
if (StringUtils.hasText(this.operation.getKey())) {
404393
EvaluationContext evaluationContext = createEvaluationContext(result);
405-
return CacheAspectSupport.this.evaluator.key(this.operation.getKey(), this.method, evaluationContext);
394+
return evaluator.key(this.operation.getKey(), this.method, evaluationContext);
406395
}
407-
return CacheAspectSupport.this.keyGenerator.generate(this.target, this.method, this.args);
396+
return keyGenerator.generate(this.target, this.method, this.args);
408397
}
409398

410399
private EvaluationContext createEvaluationContext(Object result) {
411-
return CacheAspectSupport.this.evaluator.createEvaluationContext(this.caches, this.method, this.args,
412-
this.target, this.targetClass, result);
400+
return evaluator.createEvaluationContext(this.caches, this.method, this.args, this.target, this.targetClass, result);
413401
}
414402

415403
protected Collection<Cache> getCaches() {
@@ -430,11 +418,12 @@ public CachePutRequest(CacheOperationContext context, Object key) {
430418
}
431419

432420
public void apply(Object result) {
433-
if(this.context.canPutToCache(result)) {
421+
if (this.context.canPutToCache(result)) {
434422
for (Cache cache : this.context.getCaches()) {
435423
cache.put(this.key, result);
436424
}
437425
}
438426
}
439427
}
428+
440429
}

0 commit comments

Comments
 (0)