+ refactor a bit the internals of CacheAspect to allow invocations that do not throw any exceptions (AspectJ)
This commit is contained in:
Costin Leau
2011-09-02 15:37:42 +00:00
parent 91251812b1
commit d9de19d7b3
13 changed files with 180 additions and 58 deletions

View File

@@ -21,11 +21,9 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.Callable;
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;
@@ -57,6 +55,10 @@ import org.springframework.util.StringUtils;
*/
public abstract class CacheAspectSupport implements InitializingBean {
public interface Invoker {
Object invoke();
}
protected final Log logger = LogFactory.getLog(getClass());
private CacheManager cacheManager;
@@ -171,11 +173,11 @@ public abstract class CacheAspectSupport implements InitializingBean {
return new CacheOperationContext(operation, method, args, target, targetClass);
}
protected Object execute(Callable<Object> invocation, Object target, Method method, Object[] args) throws Exception {
protected Object execute(Invoker invoker, Object target, Method method, Object[] args) {
// check whether aspect is enabled
// to cope with cases where the AJ is pulled in automatically
if (!this.initialized) {
return invocation.call();
return invoker.invoke();
}
boolean log = logger.isTraceEnabled();
@@ -224,7 +226,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
logger.trace("Key " + key + " NOT found in cache(s), invoking cached target method "
+ method);
}
retVal = invocation.call();
retVal = invoker.invoke();
// update all caches
for (Cache cache : caches) {
cache.put(key, retVal);
@@ -239,7 +241,6 @@ public abstract class CacheAspectSupport implements InitializingBean {
if (cacheOp instanceof CacheEvictOperation) {
CacheEvictOperation evictOp = (CacheEvictOperation) cacheOp;
retVal = invocation.call();
// for each cache
// lazy key initialization
@@ -266,6 +267,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
cache.evict(key);
}
}
retVal = invoker.invoke();
}
return retVal;
}
@@ -276,7 +278,7 @@ public abstract class CacheAspectSupport implements InitializingBean {
}
}
return invocation.call();
return invoker.invoke();
}

View File

@@ -18,13 +18,10 @@ package org.springframework.cache.interceptor;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.concurrent.Callable;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.ReflectionUtils;
/**
* AOP Alliance MethodInterceptor for declarative cache
* management using the common Spring caching infrastructure
@@ -44,22 +41,31 @@ import org.springframework.util.ReflectionUtils;
@SuppressWarnings("serial")
public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable {
private static class ThrowableWrapper extends RuntimeException {
private final Throwable original;
ThrowableWrapper(Throwable original) {
this.original = original;
}
}
public Object invoke(final MethodInvocation invocation) throws Throwable {
Method method = invocation.getMethod();
Callable<Object> aopAllianceInvocation = new Callable<Object>() {
public Object call() throws Exception {
Invoker aopAllianceInvoker = new Invoker() {
public Object invoke() {
try {
return invocation.proceed();
}
catch (Throwable ex) {
ReflectionUtils.rethrowException(ex);
return null;
} catch (Throwable ex) {
throw new ThrowableWrapper(ex);
}
}
};
return execute(aopAllianceInvocation, invocation.getThis(), method, invocation.getArguments());
try {
return execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments());
} catch (ThrowableWrapper th) {
throw th.original;
}
}
}
}

View File

@@ -18,6 +18,7 @@ package org.springframework.cache.interceptor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.AbstractSingletonProxyFactoryBean;
import org.springframework.aop.support.DefaultPointcutAdvisor;
/**
* Proxy factory bean for simplified declarative caching handling.
@@ -38,9 +39,26 @@ public class CacheProxyFactoryBean extends AbstractSingletonProxyFactoryBean {
private final CacheInterceptor cachingInterceptor = new CacheInterceptor();
private Pointcut pointcut;
/**
* Set a pointcut, i.e a bean that can cause conditional invocation
* of the CacheInterceptor depending on method and attributes passed.
* Note: Additional interceptors are always invoked.
* @see #setPreInterceptors
* @see #setPostInterceptors
*/
public void setPointcut(Pointcut pointcut) {
this.pointcut = pointcut;
}
@Override
protected Object createMainInterceptor() {
return null;
this.cachingInterceptor.afterPropertiesSet();
if (this.pointcut != null) {
return new DefaultPointcutAdvisor(this.pointcut, this.cachingInterceptor);
} else {
// Rely on default pointcut.
throw new UnsupportedOperationException();
}
}
/**