Skip to content

Commit

Permalink
Polishing
Browse files Browse the repository at this point in the history
  • Loading branch information
jhoeller committed Aug 5, 2013
1 parent bcbd338 commit 1245919
Showing 1 changed file with 52 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

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;
Expand Down Expand Up @@ -61,23 +62,25 @@
*/
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.
Expand All @@ -101,10 +104,8 @@ public CacheManager getCacheManager() {
*/
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]);
}

/**
Expand Down Expand Up @@ -141,6 +142,7 @@ public void afterPropertiesSet() {
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
Expand Down Expand Up @@ -191,34 +193,26 @@ protected Object execute(Invoker invoker, Object target, Method method, Object[]
// analyze caching information
if (!CollectionUtils.isEmpty(cacheOp)) {
Map<String, Collection<CacheOperationContext>> 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<CacheOperationContext, Object> 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;
}

Expand All @@ -229,21 +223,15 @@ private void inspectBeforeCacheEvicts(Collection<CacheOperationContext> eviction
inspectCacheEvicts(evictions, true, ExpressionEvaluator.NO_RESULT);
}

private void inspectAfterCacheEvicts(Collection<CacheOperationContext> evictions,
Object result) {
private void inspectAfterCacheEvicts(Collection<CacheOperationContext> evictions, Object result) {
inspectCacheEvicts(evictions, false, result);
}

private void inspectCacheEvicts(Collection<CacheOperationContext> evictions,
boolean beforeInvocation, Object result) {

private void inspectCacheEvicts(Collection<CacheOperationContext> 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
Expand All @@ -257,7 +245,8 @@ private void inspectCacheEvicts(Collection<CacheOperationContext> evictions,
if (log) {
logger.trace("Invalidating entire cache for operation " + evictOp + " on method " + context.method);
}
} else {
}
else {
// check key
if (key == null) {
key = context.generateKey();
Expand All @@ -268,7 +257,8 @@ private void inspectCacheEvicts(Collection<CacheOperationContext> evictions,
cache.evict(key);
}
}
} else {
}
else {
if (log) {
logger.trace("Cache condition failed on method " + context.method + " for operation " + context.operation);
}
Expand All @@ -279,20 +269,17 @@ private void inspectCacheEvicts(Collection<CacheOperationContext> evictions,
}

private CacheStatus inspectCacheables(Collection<CacheOperationContext> cacheables) {
Map<CacheOperationContext, Object> cUpdates = new LinkedHashMap<CacheOperationContext, Object>(cacheables.size());

Map<CacheOperationContext, Object> cacheUpdates = new LinkedHashMap<CacheOperationContext, Object>(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);
}
Expand All @@ -301,12 +288,9 @@ private CacheStatus inspectCacheables(Collection<CacheOperationContext> cacheabl
"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()) {
Expand All @@ -318,7 +302,6 @@ private CacheStatus inspectCacheables(Collection<CacheOperationContext> cacheabl
}
}
}

if (!localCacheHit) {
updateRequired = true;
}
Expand All @@ -332,38 +315,20 @@ private CacheStatus inspectCacheables(Collection<CacheOperationContext> cacheabl

// 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<CacheOperationContext, Object> cUpdates;
final boolean updateRequired;
final Object retVal;

CacheStatus(Map<CacheOperationContext, Object> cUpdates, boolean updateRequired, Object retVal) {
this.cUpdates = cUpdates;
this.updateRequired = updateRequired;
this.retVal = retVal;
}
}

private Map<CacheOperationContext, Object> inspectCacheUpdates(Collection<CacheOperationContext> updates) {

Map<CacheOperationContext, Object> cUpdates = new LinkedHashMap<CacheOperationContext, Object>(updates.size());

Map<CacheOperationContext, Object> cacheUpdates = new LinkedHashMap<CacheOperationContext, Object>(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);
}
Expand All @@ -372,9 +337,8 @@ private Map<CacheOperationContext, Object> inspectCacheUpdates(Collection<CacheO
"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) {
Expand All @@ -383,8 +347,7 @@ private Map<CacheOperationContext, Object> inspectCacheUpdates(Collection<CacheO
}
}
}

return cUpdates;
return cacheUpdates;
}

private void update(Map<CacheOperationContext, Object> updates, Object retVal) {
Expand All @@ -400,6 +363,7 @@ private void update(Map<CacheOperationContext, Object> updates, Object retVal) {

private Map<String, Collection<CacheOperationContext>> createOperationContext(Collection<CacheOperation> cacheOp,
Method method, Object[] args, Object target, Class<?> targetClass) {

Map<String, Collection<CacheOperationContext>> map = new LinkedHashMap<String, Collection<CacheOperationContext>>(3);

Collection<CacheOperationContext> cacheables = new ArrayList<CacheOperationContext>();
Expand Down Expand Up @@ -429,6 +393,13 @@ private Map<String, Collection<CacheOperationContext>> createOperationContext(Co
return map;
}


public interface Invoker {

Object invoke();
}


protected class CacheOperationContext {

private final CacheOperation operation;
Expand Down Expand Up @@ -501,4 +472,22 @@ protected Collection<Cache> getCaches() {
return this.caches;
}
}


private static class CacheStatus {

// caches/key
final Map<CacheOperationContext, Object> cacheUpdates;

final boolean updateRequired;

final Object retVal;

CacheStatus(Map<CacheOperationContext, Object> cacheUpdates, boolean updateRequired, Object retVal) {
this.cacheUpdates = cacheUpdates;
this.updateRequired = updateRequired;
this.retVal = retVal;
}
}

}

0 comments on commit 1245919

Please sign in to comment.