From 124591933159668d8b9a10d55c10c335862216d6 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 6 Aug 2013 01:15:17 +0200 Subject: [PATCH] Polishing --- .../cache/interceptor/CacheAspectSupport.java | 115 ++++++++---------- 1 file changed, 52 insertions(+), 63 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java index 8e0b36889d1..f8e2f763e78 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java @@ -25,6 +25,7 @@ import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.aop.framework.AopProxyUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.cache.Cache; @@ -61,23 +62,25 @@ import org.springframework.util.StringUtils; */ public abstract class CacheAspectSupport implements InitializingBean { - public interface Invoker { - Object invoke(); - } + private static final String CACHEABLE = "cacheable"; + + private static final String UPDATE = "cacheupdate"; + + private static final String EVICT = "cacheevict"; + protected final Log logger = LogFactory.getLog(getClass()); + private final ExpressionEvaluator evaluator = new ExpressionEvaluator(); + private CacheManager cacheManager; private CacheOperationSource cacheOperationSource; - private final ExpressionEvaluator evaluator = new ExpressionEvaluator(); - private KeyGenerator keyGenerator = new DefaultKeyGenerator(); private boolean initialized = false; - private static final String CACHEABLE = "cacheable", UPDATE = "cacheupdate", EVICT = "cacheevict"; /** * Set the CacheManager that this cache aspect should delegate to. @@ -101,10 +104,8 @@ public abstract class CacheAspectSupport implements InitializingBean { */ public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) { Assert.notEmpty(cacheOperationSources); - this.cacheOperationSource = - (cacheOperationSources.length > 1 ? - new CompositeCacheOperationSource(cacheOperationSources) : - cacheOperationSources[0]); + this.cacheOperationSource = (cacheOperationSources.length > 1 ? + new CompositeCacheOperationSource(cacheOperationSources) : cacheOperationSources[0]); } /** @@ -141,6 +142,7 @@ public abstract class CacheAspectSupport implements InitializingBean { this.initialized = true; } + /** * Convenience method to return a String representation of this Method * for use in logging. Can be overridden in subclasses to provide a @@ -191,34 +193,26 @@ public abstract class CacheAspectSupport implements InitializingBean { // analyze caching information if (!CollectionUtils.isEmpty(cacheOp)) { Map> ops = createOperationContext(cacheOp, method, args, target, targetClass); - // start with evictions inspectBeforeCacheEvicts(ops.get(EVICT)); - // follow up with cacheable CacheStatus status = inspectCacheables(ops.get(CACHEABLE)); - - Object retVal = null; + Object retVal; Map updates = inspectCacheUpdates(ops.get(UPDATE)); - if (status != null) { if (status.updateRequired) { - updates.putAll(status.cUpdates); + updates.putAll(status.cacheUpdates); } // return cached object else { return status.retVal; } } - retVal = invoker.invoke(); - inspectAfterCacheEvicts(ops.get(EVICT), retVal); - if (!updates.isEmpty()) { update(updates, retVal); } - return retVal; } @@ -229,21 +223,15 @@ public abstract class CacheAspectSupport implements InitializingBean { inspectCacheEvicts(evictions, true, ExpressionEvaluator.NO_RESULT); } - private void inspectAfterCacheEvicts(Collection evictions, - Object result) { + private void inspectAfterCacheEvicts(Collection evictions, Object result) { inspectCacheEvicts(evictions, false, result); } - private void inspectCacheEvicts(Collection evictions, - boolean beforeInvocation, Object result) { - + private void inspectCacheEvicts(Collection evictions, boolean beforeInvocation, Object result) { if (!evictions.isEmpty()) { - boolean log = logger.isTraceEnabled(); - for (CacheOperationContext context : evictions) { CacheEvictOperation evictOp = (CacheEvictOperation) context.operation; - if (beforeInvocation == evictOp.isBeforeInvocation()) { if (context.isConditionPassing(result)) { // for each cache @@ -257,7 +245,8 @@ public abstract class CacheAspectSupport implements InitializingBean { if (log) { logger.trace("Invalidating entire cache for operation " + evictOp + " on method " + context.method); } - } else { + } + else { // check key if (key == null) { key = context.generateKey(); @@ -268,7 +257,8 @@ public abstract class CacheAspectSupport implements InitializingBean { cache.evict(key); } } - } else { + } + else { if (log) { logger.trace("Cache condition failed on method " + context.method + " for operation " + context.operation); } @@ -279,20 +269,17 @@ public abstract class CacheAspectSupport implements InitializingBean { } private CacheStatus inspectCacheables(Collection cacheables) { - Map cUpdates = new LinkedHashMap(cacheables.size()); - + Map cacheUpdates = new LinkedHashMap(cacheables.size()); boolean updateRequired = false; Object retVal = null; if (!cacheables.isEmpty()) { boolean log = logger.isTraceEnabled(); boolean atLeastOnePassed = false; - for (CacheOperationContext context : cacheables) { if (context.isConditionPassing()) { atLeastOnePassed = true; Object key = context.generateKey(); - if (log) { logger.trace("Computed cache key " + key + " for operation " + context.operation); } @@ -301,12 +288,9 @@ public abstract class CacheAspectSupport implements InitializingBean { "Null key returned for cache operation (maybe you are using named params on classes without debug info?) " + context.operation); } - // add op/key (in case an update is discovered later on) - cUpdates.put(context, key); - + cacheUpdates.put(context, key); boolean localCacheHit = false; - // check whether the cache needs to be inspected or not (the method will be invoked anyway) if (!updateRequired) { for (Cache cache : context.getCaches()) { @@ -318,7 +302,6 @@ public abstract class CacheAspectSupport implements InitializingBean { } } } - if (!localCacheHit) { updateRequired = true; } @@ -332,38 +315,20 @@ public abstract class CacheAspectSupport implements InitializingBean { // return a status only if at least on cacheable matched if (atLeastOnePassed) { - return new CacheStatus(cUpdates, updateRequired, retVal); + return new CacheStatus(cacheUpdates, updateRequired, retVal); } } return null; } - private static class CacheStatus { - // caches/key - final Map cUpdates; - final boolean updateRequired; - final Object retVal; - - CacheStatus(Map cUpdates, boolean updateRequired, Object retVal) { - this.cUpdates = cUpdates; - this.updateRequired = updateRequired; - this.retVal = retVal; - } - } - private Map inspectCacheUpdates(Collection updates) { - - Map cUpdates = new LinkedHashMap(updates.size()); - + Map cacheUpdates = new LinkedHashMap(updates.size()); if (!updates.isEmpty()) { boolean log = logger.isTraceEnabled(); - for (CacheOperationContext context : updates) { if (context.isConditionPassing()) { - Object key = context.generateKey(); - if (log) { logger.trace("Computed cache key " + key + " for operation " + context.operation); } @@ -372,9 +337,8 @@ public abstract class CacheAspectSupport implements InitializingBean { "Null key returned for cache operation (maybe you are using named params on classes without debug info?) " + context.operation); } - // add op/key (in case an update is discovered later on) - cUpdates.put(context, key); + cacheUpdates.put(context, key); } else { if (log) { @@ -383,8 +347,7 @@ public abstract class CacheAspectSupport implements InitializingBean { } } } - - return cUpdates; + return cacheUpdates; } private void update(Map updates, Object retVal) { @@ -400,6 +363,7 @@ public abstract class CacheAspectSupport implements InitializingBean { private Map> createOperationContext(Collection cacheOp, Method method, Object[] args, Object target, Class targetClass) { + Map> map = new LinkedHashMap>(3); Collection cacheables = new ArrayList(); @@ -429,6 +393,13 @@ public abstract class CacheAspectSupport implements InitializingBean { return map; } + + public interface Invoker { + + Object invoke(); + } + + protected class CacheOperationContext { private final CacheOperation operation; @@ -501,4 +472,22 @@ public abstract class CacheAspectSupport implements InitializingBean { return this.caches; } } + + + private static class CacheStatus { + + // caches/key + final Map cacheUpdates; + + final boolean updateRequired; + + final Object retVal; + + CacheStatus(Map cacheUpdates, boolean updateRequired, Object retVal) { + this.cacheUpdates = cacheUpdates; + this.updateRequired = updateRequired; + this.retVal = retVal; + } + } + }