25
25
26
26
import org .apache .commons .logging .Log ;
27
27
import org .apache .commons .logging .LogFactory ;
28
+
28
29
import org .springframework .aop .framework .AopProxyUtils ;
29
30
import org .springframework .beans .factory .InitializingBean ;
30
31
import org .springframework .cache .Cache ;
61
62
*/
62
63
public abstract class CacheAspectSupport implements InitializingBean {
63
64
64
- public interface Invoker {
65
- Object invoke ();
66
- }
65
+ private static final String CACHEABLE = "cacheable" ;
66
+
67
+ private static final String UPDATE = "cacheupdate" ;
68
+
69
+ private static final String EVICT = "cacheevict" ;
70
+
67
71
68
72
protected final Log logger = LogFactory .getLog (getClass ());
69
73
74
+ private final ExpressionEvaluator evaluator = new ExpressionEvaluator ();
75
+
70
76
private CacheManager cacheManager ;
71
77
72
78
private CacheOperationSource cacheOperationSource ;
73
79
74
- private final ExpressionEvaluator evaluator = new ExpressionEvaluator ();
75
-
76
80
private KeyGenerator keyGenerator = new DefaultKeyGenerator ();
77
81
78
82
private boolean initialized = false ;
79
83
80
- private static final String CACHEABLE = "cacheable" , UPDATE = "cacheupdate" , EVICT = "cacheevict" ;
81
84
82
85
/**
83
86
* Set the CacheManager that this cache aspect should delegate to.
@@ -101,10 +104,8 @@ public CacheManager getCacheManager() {
101
104
*/
102
105
public void setCacheOperationSources (CacheOperationSource ... cacheOperationSources ) {
103
106
Assert .notEmpty (cacheOperationSources );
104
- this .cacheOperationSource =
105
- (cacheOperationSources .length > 1 ?
106
- new CompositeCacheOperationSource (cacheOperationSources ) :
107
- cacheOperationSources [0 ]);
107
+ this .cacheOperationSource = (cacheOperationSources .length > 1 ?
108
+ new CompositeCacheOperationSource (cacheOperationSources ) : cacheOperationSources [0 ]);
108
109
}
109
110
110
111
/**
@@ -141,6 +142,7 @@ public void afterPropertiesSet() {
141
142
this .initialized = true ;
142
143
}
143
144
145
+
144
146
/**
145
147
* Convenience method to return a String representation of this Method
146
148
* for use in logging. Can be overridden in subclasses to provide a
@@ -191,34 +193,26 @@ protected Object execute(Invoker invoker, Object target, Method method, Object[]
191
193
// analyze caching information
192
194
if (!CollectionUtils .isEmpty (cacheOp )) {
193
195
Map <String , Collection <CacheOperationContext >> ops = createOperationContext (cacheOp , method , args , target , targetClass );
194
-
195
196
// start with evictions
196
197
inspectBeforeCacheEvicts (ops .get (EVICT ));
197
-
198
198
// follow up with cacheable
199
199
CacheStatus status = inspectCacheables (ops .get (CACHEABLE ));
200
-
201
- Object retVal = null ;
200
+ Object retVal ;
202
201
Map <CacheOperationContext , Object > updates = inspectCacheUpdates (ops .get (UPDATE ));
203
-
204
202
if (status != null ) {
205
203
if (status .updateRequired ) {
206
- updates .putAll (status .cUpdates );
204
+ updates .putAll (status .cacheUpdates );
207
205
}
208
206
// return cached object
209
207
else {
210
208
return status .retVal ;
211
209
}
212
210
}
213
-
214
211
retVal = invoker .invoke ();
215
-
216
212
inspectAfterCacheEvicts (ops .get (EVICT ), retVal );
217
-
218
213
if (!updates .isEmpty ()) {
219
214
update (updates , retVal );
220
215
}
221
-
222
216
return retVal ;
223
217
}
224
218
@@ -229,21 +223,15 @@ private void inspectBeforeCacheEvicts(Collection<CacheOperationContext> eviction
229
223
inspectCacheEvicts (evictions , true , ExpressionEvaluator .NO_RESULT );
230
224
}
231
225
232
- private void inspectAfterCacheEvicts (Collection <CacheOperationContext > evictions ,
233
- Object result ) {
226
+ private void inspectAfterCacheEvicts (Collection <CacheOperationContext > evictions , Object result ) {
234
227
inspectCacheEvicts (evictions , false , result );
235
228
}
236
229
237
- private void inspectCacheEvicts (Collection <CacheOperationContext > evictions ,
238
- boolean beforeInvocation , Object result ) {
239
-
230
+ private void inspectCacheEvicts (Collection <CacheOperationContext > evictions , boolean beforeInvocation , Object result ) {
240
231
if (!evictions .isEmpty ()) {
241
-
242
232
boolean log = logger .isTraceEnabled ();
243
-
244
233
for (CacheOperationContext context : evictions ) {
245
234
CacheEvictOperation evictOp = (CacheEvictOperation ) context .operation ;
246
-
247
235
if (beforeInvocation == evictOp .isBeforeInvocation ()) {
248
236
if (context .isConditionPassing (result )) {
249
237
// for each cache
@@ -257,7 +245,8 @@ private void inspectCacheEvicts(Collection<CacheOperationContext> evictions,
257
245
if (log ) {
258
246
logger .trace ("Invalidating entire cache for operation " + evictOp + " on method " + context .method );
259
247
}
260
- } else {
248
+ }
249
+ else {
261
250
// check key
262
251
if (key == null ) {
263
252
key = context .generateKey ();
@@ -268,7 +257,8 @@ private void inspectCacheEvicts(Collection<CacheOperationContext> evictions,
268
257
cache .evict (key );
269
258
}
270
259
}
271
- } else {
260
+ }
261
+ else {
272
262
if (log ) {
273
263
logger .trace ("Cache condition failed on method " + context .method + " for operation " + context .operation );
274
264
}
@@ -279,20 +269,17 @@ private void inspectCacheEvicts(Collection<CacheOperationContext> evictions,
279
269
}
280
270
281
271
private CacheStatus inspectCacheables (Collection <CacheOperationContext > cacheables ) {
282
- Map <CacheOperationContext , Object > cUpdates = new LinkedHashMap <CacheOperationContext , Object >(cacheables .size ());
283
-
272
+ Map <CacheOperationContext , Object > cacheUpdates = new LinkedHashMap <CacheOperationContext , Object >(cacheables .size ());
284
273
boolean updateRequired = false ;
285
274
Object retVal = null ;
286
275
287
276
if (!cacheables .isEmpty ()) {
288
277
boolean log = logger .isTraceEnabled ();
289
278
boolean atLeastOnePassed = false ;
290
-
291
279
for (CacheOperationContext context : cacheables ) {
292
280
if (context .isConditionPassing ()) {
293
281
atLeastOnePassed = true ;
294
282
Object key = context .generateKey ();
295
-
296
283
if (log ) {
297
284
logger .trace ("Computed cache key " + key + " for operation " + context .operation );
298
285
}
@@ -301,12 +288,9 @@ private CacheStatus inspectCacheables(Collection<CacheOperationContext> cacheabl
301
288
"Null key returned for cache operation (maybe you are using named params on classes without debug info?) "
302
289
+ context .operation );
303
290
}
304
-
305
291
// add op/key (in case an update is discovered later on)
306
- cUpdates .put (context , key );
307
-
292
+ cacheUpdates .put (context , key );
308
293
boolean localCacheHit = false ;
309
-
310
294
// check whether the cache needs to be inspected or not (the method will be invoked anyway)
311
295
if (!updateRequired ) {
312
296
for (Cache cache : context .getCaches ()) {
@@ -318,7 +302,6 @@ private CacheStatus inspectCacheables(Collection<CacheOperationContext> cacheabl
318
302
}
319
303
}
320
304
}
321
-
322
305
if (!localCacheHit ) {
323
306
updateRequired = true ;
324
307
}
@@ -332,38 +315,20 @@ private CacheStatus inspectCacheables(Collection<CacheOperationContext> cacheabl
332
315
333
316
// return a status only if at least on cacheable matched
334
317
if (atLeastOnePassed ) {
335
- return new CacheStatus (cUpdates , updateRequired , retVal );
318
+ return new CacheStatus (cacheUpdates , updateRequired , retVal );
336
319
}
337
320
}
338
321
339
322
return null ;
340
323
}
341
324
342
- private static class CacheStatus {
343
- // caches/key
344
- final Map <CacheOperationContext , Object > cUpdates ;
345
- final boolean updateRequired ;
346
- final Object retVal ;
347
-
348
- CacheStatus (Map <CacheOperationContext , Object > cUpdates , boolean updateRequired , Object retVal ) {
349
- this .cUpdates = cUpdates ;
350
- this .updateRequired = updateRequired ;
351
- this .retVal = retVal ;
352
- }
353
- }
354
-
355
325
private Map <CacheOperationContext , Object > inspectCacheUpdates (Collection <CacheOperationContext > updates ) {
356
-
357
- Map <CacheOperationContext , Object > cUpdates = new LinkedHashMap <CacheOperationContext , Object >(updates .size ());
358
-
326
+ Map <CacheOperationContext , Object > cacheUpdates = new LinkedHashMap <CacheOperationContext , Object >(updates .size ());
359
327
if (!updates .isEmpty ()) {
360
328
boolean log = logger .isTraceEnabled ();
361
-
362
329
for (CacheOperationContext context : updates ) {
363
330
if (context .isConditionPassing ()) {
364
-
365
331
Object key = context .generateKey ();
366
-
367
332
if (log ) {
368
333
logger .trace ("Computed cache key " + key + " for operation " + context .operation );
369
334
}
@@ -372,9 +337,8 @@ private Map<CacheOperationContext, Object> inspectCacheUpdates(Collection<CacheO
372
337
"Null key returned for cache operation (maybe you are using named params on classes without debug info?) "
373
338
+ context .operation );
374
339
}
375
-
376
340
// add op/key (in case an update is discovered later on)
377
- cUpdates .put (context , key );
341
+ cacheUpdates .put (context , key );
378
342
}
379
343
else {
380
344
if (log ) {
@@ -383,8 +347,7 @@ private Map<CacheOperationContext, Object> inspectCacheUpdates(Collection<CacheO
383
347
}
384
348
}
385
349
}
386
-
387
- return cUpdates ;
350
+ return cacheUpdates ;
388
351
}
389
352
390
353
private void update (Map <CacheOperationContext , Object > updates , Object retVal ) {
@@ -400,6 +363,7 @@ private void update(Map<CacheOperationContext, Object> updates, Object retVal) {
400
363
401
364
private Map <String , Collection <CacheOperationContext >> createOperationContext (Collection <CacheOperation > cacheOp ,
402
365
Method method , Object [] args , Object target , Class <?> targetClass ) {
366
+
403
367
Map <String , Collection <CacheOperationContext >> map = new LinkedHashMap <String , Collection <CacheOperationContext >>(3 );
404
368
405
369
Collection <CacheOperationContext > cacheables = new ArrayList <CacheOperationContext >();
@@ -429,6 +393,13 @@ private Map<String, Collection<CacheOperationContext>> createOperationContext(Co
429
393
return map ;
430
394
}
431
395
396
+
397
+ public interface Invoker {
398
+
399
+ Object invoke ();
400
+ }
401
+
402
+
432
403
protected class CacheOperationContext {
433
404
434
405
private final CacheOperation operation ;
@@ -501,4 +472,22 @@ protected Collection<Cache> getCaches() {
501
472
return this .caches ;
502
473
}
503
474
}
475
+
476
+
477
+ private static class CacheStatus {
478
+
479
+ // caches/key
480
+ final Map <CacheOperationContext , Object > cacheUpdates ;
481
+
482
+ final boolean updateRequired ;
483
+
484
+ final Object retVal ;
485
+
486
+ CacheStatus (Map <CacheOperationContext , Object > cacheUpdates , boolean updateRequired , Object retVal ) {
487
+ this .cacheUpdates = cacheUpdates ;
488
+ this .updateRequired = updateRequired ;
489
+ this .retVal = retVal ;
490
+ }
491
+ }
492
+
504
493
}
0 commit comments