polishing
This commit is contained in:
parent
5be1ff281c
commit
d9e0b292ab
|
|
@ -29,8 +29,8 @@ import javax.cache.annotation.CacheResult;
|
||||||
import javax.cache.annotation.CacheValue;
|
import javax.cache.annotation.CacheValue;
|
||||||
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.cache.interceptor.SimpleKeyGenerator;
|
||||||
import org.springframework.cache.jcache.config.JCacheableService;
|
import org.springframework.cache.jcache.config.JCacheableService;
|
||||||
import org.springframework.cache.jcache.interceptor.SimpleGeneratedCacheKey;
|
|
||||||
import org.springframework.cache.jcache.support.TestableCacheKeyGenerator;
|
import org.springframework.cache.jcache.support.TestableCacheKeyGenerator;
|
||||||
import org.springframework.cache.jcache.support.TestableCacheResolverFactory;
|
import org.springframework.cache.jcache.support.TestableCacheResolverFactory;
|
||||||
|
|
||||||
|
|
@ -111,7 +111,7 @@ public class AnnotatedJCacheableService implements JCacheableService<Long> {
|
||||||
@Override
|
@Override
|
||||||
@CachePut(afterInvocation = false)
|
@CachePut(afterInvocation = false)
|
||||||
public void earlyPut(String id, @CacheValue Object value) {
|
public void earlyPut(String id, @CacheValue Object value) {
|
||||||
SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(id);
|
Object key = SimpleKeyGenerator.generateKey(id);
|
||||||
Cache.ValueWrapper valueWrapper = defaultCache.get(key);
|
Cache.ValueWrapper valueWrapper = defaultCache.get(key);
|
||||||
if (valueWrapper == null) {
|
if (valueWrapper == null) {
|
||||||
throw new AssertionError("Excepted value to be put in cache with key " + key);
|
throw new AssertionError("Excepted value to be put in cache with key " + key);
|
||||||
|
|
@ -143,7 +143,7 @@ public class AnnotatedJCacheableService implements JCacheableService<Long> {
|
||||||
@Override
|
@Override
|
||||||
@CacheRemove(afterInvocation = false)
|
@CacheRemove(afterInvocation = false)
|
||||||
public void earlyRemove(String id) {
|
public void earlyRemove(String id) {
|
||||||
SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(id);
|
Object key = SimpleKeyGenerator.generateKey(id);
|
||||||
Cache.ValueWrapper valueWrapper = defaultCache.get(key);
|
Cache.ValueWrapper valueWrapper = defaultCache.get(key);
|
||||||
if (valueWrapper != null) {
|
if (valueWrapper != null) {
|
||||||
throw new AssertionError("Value with key " + key + " expected to be already remove from cache");
|
throw new AssertionError("Value with key " + key + " expected to be already remove from cache");
|
||||||
|
|
|
||||||
|
|
@ -49,18 +49,17 @@ public class AbstractJCacheConfiguration extends AbstractCachingConfiguration<JC
|
||||||
public JCacheOperationSource cacheOperationSource() {
|
public JCacheOperationSource cacheOperationSource() {
|
||||||
DefaultJCacheOperationSource source = new DefaultJCacheOperationSource();
|
DefaultJCacheOperationSource source = new DefaultJCacheOperationSource();
|
||||||
if (this.cacheManager != null) {
|
if (this.cacheManager != null) {
|
||||||
source.setCacheManager(cacheManager);
|
source.setCacheManager(this.cacheManager);
|
||||||
}
|
}
|
||||||
if (keyGenerator != null) {
|
if (this.keyGenerator != null) {
|
||||||
source.setKeyGenerator(keyGenerator);
|
source.setKeyGenerator(this.keyGenerator);
|
||||||
}
|
}
|
||||||
if (this.cacheResolver != null) {
|
if (this.cacheResolver != null) {
|
||||||
source.setCacheResolver(cacheResolver);
|
source.setCacheResolver(this.cacheResolver);
|
||||||
}
|
}
|
||||||
if (this.exceptionCacheResolver != null) {
|
if (this.exceptionCacheResolver != null) {
|
||||||
source.setExceptionCacheResolver(exceptionCacheResolver);
|
source.setExceptionCacheResolver(this.exceptionCacheResolver);
|
||||||
}
|
}
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ import org.springframework.cache.interceptor.AbstractCacheInvoker;
|
||||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||||
import org.springframework.cache.jcache.model.BaseCacheOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base interceptor for JSR-107 cache annotations.
|
* A base interceptor for JSR-107 cache annotations.
|
||||||
|
|
@ -37,7 +36,7 @@ import org.springframework.cache.jcache.model.BaseCacheOperation;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public abstract class AbstractCacheInterceptor<O extends BaseCacheOperation<A>, A extends Annotation>
|
abstract class AbstractCacheInterceptor<O extends AbstractJCacheOperation<A>, A extends Annotation>
|
||||||
extends AbstractCacheInvoker implements Serializable {
|
extends AbstractCacheInvoker implements Serializable {
|
||||||
|
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.cache.interceptor.MethodCacheKey;
|
import org.springframework.cache.interceptor.MethodCacheKey;
|
||||||
import org.springframework.cache.jcache.model.JCacheOperation;
|
|
||||||
import org.springframework.core.BridgeMethodResolver;
|
import org.springframework.core.BridgeMethodResolver;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
|
||||||
|
|
@ -58,7 +57,7 @@ public abstract class AbstractFallbackJCacheOperationSource
|
||||||
return cached;
|
return cached;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
JCacheOperation<?> operation = computeCacheOperations(method, targetClass);
|
JCacheOperation<?> operation = computeCacheOperation(method, targetClass);
|
||||||
if (operation != null) {
|
if (operation != null) {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Adding cacheable method '" + method.getName()
|
logger.debug("Adding cacheable method '" + method.getName()
|
||||||
|
|
@ -70,7 +69,7 @@ public abstract class AbstractFallbackJCacheOperationSource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private JCacheOperation<?> computeCacheOperations(Method method, Class<?> targetClass) {
|
private JCacheOperation<?> computeCacheOperation(Method method, Class<?> targetClass) {
|
||||||
// Don't allow no-public methods as required.
|
// Don't allow no-public methods as required.
|
||||||
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
|
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
@ -32,30 +32,33 @@ import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public abstract class BaseKeyCacheOperation<A extends Annotation> extends BaseCacheOperation<A> {
|
abstract class AbstractJCacheKeyOperation<A extends Annotation> extends AbstractJCacheOperation<A> {
|
||||||
|
|
||||||
private final KeyGenerator keyGenerator;
|
private final KeyGenerator keyGenerator;
|
||||||
|
|
||||||
private final List<CacheParameterDetail> keyParameterDetails;
|
private final List<CacheParameterDetail> keyParameterDetails;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance.
|
* Create a new instance.
|
||||||
* @param methodDetails the {@link CacheMethodDetails} related to the cached method
|
* @param methodDetails the {@link CacheMethodDetails} related to the cached method
|
||||||
* @param cacheResolver the cache resolver to resolve regular caches
|
* @param cacheResolver the cache resolver to resolve regular caches
|
||||||
* @param keyGenerator the key generator to compute cache keys
|
* @param keyGenerator the key generator to compute cache keys
|
||||||
*/
|
*/
|
||||||
protected BaseKeyCacheOperation(CacheMethodDetails<A> methodDetails,
|
protected AbstractJCacheKeyOperation(CacheMethodDetails<A> methodDetails,
|
||||||
CacheResolver cacheResolver, KeyGenerator keyGenerator) {
|
CacheResolver cacheResolver, KeyGenerator keyGenerator) {
|
||||||
|
|
||||||
super(methodDetails, cacheResolver);
|
super(methodDetails, cacheResolver);
|
||||||
this.keyGenerator = keyGenerator;
|
this.keyGenerator = keyGenerator;
|
||||||
this.keyParameterDetails = initializeKeyParameterDetails(allParameterDetails);
|
this.keyParameterDetails = initializeKeyParameterDetails(this.allParameterDetails);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the {@link KeyGenerator} to use to compute cache keys.
|
* Return the {@link KeyGenerator} to use to compute cache keys.
|
||||||
*/
|
*/
|
||||||
public KeyGenerator getKeyGenerator() {
|
public KeyGenerator getKeyGenerator() {
|
||||||
return keyGenerator;
|
return this.keyGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -72,7 +75,7 @@ public abstract class BaseKeyCacheOperation<A extends Annotation> extends BaseCa
|
||||||
*/
|
*/
|
||||||
public CacheInvocationParameter[] getKeyParameters(Object... values) {
|
public CacheInvocationParameter[] getKeyParameters(Object... values) {
|
||||||
List<CacheInvocationParameter> result = new ArrayList<CacheInvocationParameter>();
|
List<CacheInvocationParameter> result = new ArrayList<CacheInvocationParameter>();
|
||||||
for (CacheParameterDetail keyParameterDetail : keyParameterDetails) {
|
for (CacheParameterDetail keyParameterDetail : this.keyParameterDetails) {
|
||||||
int parameterPosition = keyParameterDetail.getParameterPosition();
|
int parameterPosition = keyParameterDetail.getParameterPosition();
|
||||||
if (parameterPosition >= values.length) {
|
if (parameterPosition >= values.length) {
|
||||||
throw new IllegalStateException("Values mismatch, key parameter at position "
|
throw new IllegalStateException("Values mismatch, key parameter at position "
|
||||||
|
|
@ -95,7 +98,7 @@ public abstract class BaseKeyCacheOperation<A extends Annotation> extends BaseCa
|
||||||
annotated.add(allParameter);
|
annotated.add(allParameter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return annotated.size() == 0 ? all : annotated;
|
return (annotated.isEmpty() ? all : annotated);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
@ -40,7 +40,7 @@ import static java.util.Arrays.*;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public abstract class BaseCacheOperation<A extends Annotation> implements JCacheOperation<A> {
|
abstract class AbstractJCacheOperation<A extends Annotation> implements JCacheOperation<A> {
|
||||||
|
|
||||||
private final CacheMethodDetails<A> methodDetails;
|
private final CacheMethodDetails<A> methodDetails;
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ public abstract class BaseCacheOperation<A extends Annotation> implements JCache
|
||||||
* @param methodDetails the {@link CacheMethodDetails} related to the cached method
|
* @param methodDetails the {@link CacheMethodDetails} related to the cached method
|
||||||
* @param cacheResolver the cache resolver to resolve regular caches
|
* @param cacheResolver the cache resolver to resolve regular caches
|
||||||
*/
|
*/
|
||||||
protected BaseCacheOperation(CacheMethodDetails<A> methodDetails, CacheResolver cacheResolver) {
|
protected AbstractJCacheOperation(CacheMethodDetails<A> methodDetails, CacheResolver cacheResolver) {
|
||||||
Assert.notNull(methodDetails, "method details must not be null.");
|
Assert.notNull(methodDetails, "method details must not be null.");
|
||||||
Assert.notNull(cacheResolver, "cache resolver must not be null.");
|
Assert.notNull(cacheResolver, "cache resolver must not be null.");
|
||||||
this.methodDetails = methodDetails;
|
this.methodDetails = methodDetails;
|
||||||
|
|
@ -159,13 +159,13 @@ public abstract class BaseCacheOperation<A extends Annotation> implements JCache
|
||||||
|
|
||||||
private final boolean isValue;
|
private final boolean isValue;
|
||||||
|
|
||||||
public CacheParameterDetail(Method m, int parameterPosition) {
|
public CacheParameterDetail(Method method, int parameterPosition) {
|
||||||
this.rawType = m.getParameterTypes()[parameterPosition];
|
this.rawType = method.getParameterTypes()[parameterPosition];
|
||||||
this.annotations = new LinkedHashSet<Annotation>();
|
this.annotations = new LinkedHashSet<Annotation>();
|
||||||
boolean foundKeyAnnotation = false;
|
boolean foundKeyAnnotation = false;
|
||||||
boolean foundValueAnnotation = false;
|
boolean foundValueAnnotation = false;
|
||||||
for (Annotation annotation : m.getParameterAnnotations()[parameterPosition]) {
|
for (Annotation annotation : method.getParameterAnnotations()[parameterPosition]) {
|
||||||
annotations.add(annotation);
|
this.annotations.add(annotation);
|
||||||
if (CacheKey.class.isAssignableFrom(annotation.annotationType())) {
|
if (CacheKey.class.isAssignableFrom(annotation.annotationType())) {
|
||||||
foundKeyAnnotation = true;
|
foundKeyAnnotation = true;
|
||||||
}
|
}
|
||||||
|
|
@ -23,7 +23,6 @@ import javax.cache.annotation.CacheKeyInvocationContext;
|
||||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.interceptor.KeyGenerator;
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
import org.springframework.cache.jcache.model.BaseKeyCacheOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A base interceptor for JSR-107 key-based cache annotations.
|
* A base interceptor for JSR-107 key-based cache annotations.
|
||||||
|
|
@ -32,7 +31,7 @@ import org.springframework.cache.jcache.model.BaseKeyCacheOperation;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public abstract class AbstractKeyCacheInterceptor<O extends BaseKeyCacheOperation<A>, A extends Annotation>
|
abstract class AbstractKeyCacheInterceptor<O extends AbstractJCacheKeyOperation<A>, A extends Annotation>
|
||||||
extends AbstractCacheInterceptor<O, A> {
|
extends AbstractCacheInterceptor<O, A> {
|
||||||
|
|
||||||
protected AbstractKeyCacheInterceptor(CacheErrorHandler errorHandler) {
|
protected AbstractKeyCacheInterceptor(CacheErrorHandler errorHandler) {
|
||||||
|
|
|
||||||
|
|
@ -32,12 +32,6 @@ import javax.cache.annotation.CacheResult;
|
||||||
|
|
||||||
import org.springframework.cache.interceptor.CacheResolver;
|
import org.springframework.cache.interceptor.CacheResolver;
|
||||||
import org.springframework.cache.interceptor.KeyGenerator;
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
import org.springframework.cache.jcache.model.CachePutOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CacheRemoveAllOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CacheRemoveOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CacheResultOperation;
|
|
||||||
import org.springframework.cache.jcache.model.DefaultCacheMethodDetails;
|
|
||||||
import org.springframework.cache.jcache.model.JCacheOperation;
|
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -48,8 +42,7 @@ import org.springframework.util.StringUtils;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public abstract class AnnotationCacheOperationSource
|
public abstract class AnnotationJCacheOperationSource extends AbstractFallbackJCacheOperationSource {
|
||||||
extends AbstractFallbackJCacheOperationSource {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locate or create an instance of the specified {@code type}.
|
* Locate or create an instance of the specified {@code type}.
|
||||||
|
|
@ -236,7 +229,6 @@ public abstract class AnnotationCacheOperationSource
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a default cache name for the specified {@link Method}.
|
* Generate a default cache name for the specified {@link Method}.
|
||||||
*
|
|
||||||
* @param method the annotated method
|
* @param method the annotated method
|
||||||
* @return the default cache name, according to JSR-107
|
* @return the default cache name, according to JSR-107
|
||||||
*/
|
*/
|
||||||
|
|
@ -23,7 +23,6 @@ import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||||
import org.springframework.cache.jcache.model.CachePutOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercept methods annotated with {@link CachePut}.
|
* Intercept methods annotated with {@link CachePut}.
|
||||||
|
|
@ -32,7 +31,7 @@ import org.springframework.cache.jcache.model.CachePutOperation;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class CachePutInterceptor extends AbstractKeyCacheInterceptor<CachePutOperation, CachePut> {
|
class CachePutInterceptor extends AbstractKeyCacheInterceptor<CachePutOperation, CachePut> {
|
||||||
|
|
||||||
public CachePutInterceptor(CacheErrorHandler errorHandler) {
|
public CachePutInterceptor(CacheErrorHandler errorHandler) {
|
||||||
super(errorHandler);
|
super(errorHandler);
|
||||||
|
|
@ -41,11 +40,12 @@ public class CachePutInterceptor extends AbstractKeyCacheInterceptor<CachePutOpe
|
||||||
@Override
|
@Override
|
||||||
protected Object invoke(CacheOperationInvocationContext<CachePutOperation> context,
|
protected Object invoke(CacheOperationInvocationContext<CachePutOperation> context,
|
||||||
CacheOperationInvoker invoker) {
|
CacheOperationInvoker invoker) {
|
||||||
|
|
||||||
CacheKeyInvocationContext<CachePut> invocationContext = createCacheKeyInvocationContext(context);
|
CacheKeyInvocationContext<CachePut> invocationContext = createCacheKeyInvocationContext(context);
|
||||||
CachePutOperation operation = context.getOperation();
|
CachePutOperation operation = context.getOperation();
|
||||||
|
|
||||||
final boolean earlyPut = operation.isEarlyPut();
|
boolean earlyPut = operation.isEarlyPut();
|
||||||
final Object value = invocationContext.getValueParameter().getValue();
|
Object value = invocationContext.getValueParameter().getValue();
|
||||||
|
|
||||||
if (earlyPut) {
|
if (earlyPut) {
|
||||||
cacheValue(context, value);
|
cacheValue(context, value);
|
||||||
|
|
@ -58,12 +58,12 @@ public class CachePutInterceptor extends AbstractKeyCacheInterceptor<CachePutOpe
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (CacheOperationInvoker.ThrowableWrapper t) {
|
catch (CacheOperationInvoker.ThrowableWrapper ex) {
|
||||||
Throwable ex = t.getOriginal();
|
Throwable original = ex.getOriginal();
|
||||||
if (!earlyPut && operation.getExceptionTypeFilter().match(ex.getClass())) {
|
if (!earlyPut && operation.getExceptionTypeFilter().match(original.getClass())) {
|
||||||
cacheValue(context, value);
|
cacheValue(context, value);
|
||||||
}
|
}
|
||||||
throw t;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -34,7 +34,7 @@ import org.springframework.util.ExceptionTypeFilter;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
* @see CachePut
|
* @see CachePut
|
||||||
*/
|
*/
|
||||||
public class CachePutOperation extends BaseKeyCacheOperation<CachePut> {
|
class CachePutOperation extends AbstractJCacheKeyOperation<CachePut> {
|
||||||
|
|
||||||
private final ExceptionTypeFilter exceptionTypeFilter;
|
private final ExceptionTypeFilter exceptionTypeFilter;
|
||||||
|
|
||||||
|
|
@ -47,8 +47,8 @@ public class CachePutOperation extends BaseKeyCacheOperation<CachePut> {
|
||||||
super(methodDetails, cacheResolver, keyGenerator);
|
super(methodDetails, cacheResolver, keyGenerator);
|
||||||
CachePut ann = methodDetails.getCacheAnnotation();
|
CachePut ann = methodDetails.getCacheAnnotation();
|
||||||
this.exceptionTypeFilter = createExceptionTypeFilter(ann.cacheFor(), ann.noCacheFor());
|
this.exceptionTypeFilter = createExceptionTypeFilter(ann.cacheFor(), ann.noCacheFor());
|
||||||
this.valueParameterDetail = initializeValueParameterDetail(methodDetails.getMethod(), allParameterDetails);
|
this.valueParameterDetail = initializeValueParameterDetail(methodDetails.getMethod(), this.allParameterDetails);
|
||||||
if (valueParameterDetail == null) {
|
if (this.valueParameterDetail == null) {
|
||||||
throw new IllegalArgumentException("No parameter annotated with @CacheValue was found for " +
|
throw new IllegalArgumentException("No parameter annotated with @CacheValue was found for " +
|
||||||
"" + methodDetails.getMethod());
|
"" + methodDetails.getMethod());
|
||||||
}
|
}
|
||||||
|
|
@ -22,7 +22,6 @@ import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||||
import org.springframework.cache.jcache.model.CacheRemoveAllOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercept methods annotated with {@link CacheRemoveAll}.
|
* Intercept methods annotated with {@link CacheRemoveAll}.
|
||||||
|
|
@ -31,7 +30,7 @@ import org.springframework.cache.jcache.model.CacheRemoveAllOperation;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class CacheRemoveAllInterceptor
|
class CacheRemoveAllInterceptor
|
||||||
extends AbstractCacheInterceptor<CacheRemoveAllOperation, CacheRemoveAll> {
|
extends AbstractCacheInterceptor<CacheRemoveAllOperation, CacheRemoveAll> {
|
||||||
|
|
||||||
protected CacheRemoveAllInterceptor(CacheErrorHandler errorHandler) {
|
protected CacheRemoveAllInterceptor(CacheErrorHandler errorHandler) {
|
||||||
|
|
@ -41,9 +40,10 @@ public class CacheRemoveAllInterceptor
|
||||||
@Override
|
@Override
|
||||||
protected Object invoke(CacheOperationInvocationContext<CacheRemoveAllOperation> context,
|
protected Object invoke(CacheOperationInvocationContext<CacheRemoveAllOperation> context,
|
||||||
CacheOperationInvoker invoker) {
|
CacheOperationInvoker invoker) {
|
||||||
|
|
||||||
CacheRemoveAllOperation operation = context.getOperation();
|
CacheRemoveAllOperation operation = context.getOperation();
|
||||||
|
|
||||||
final boolean earlyRemove = operation.isEarlyRemove();
|
boolean earlyRemove = operation.isEarlyRemove();
|
||||||
|
|
||||||
if (earlyRemove) {
|
if (earlyRemove) {
|
||||||
removeAll(context);
|
removeAll(context);
|
||||||
|
|
@ -56,12 +56,12 @@ public class CacheRemoveAllInterceptor
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
catch (CacheOperationInvoker.ThrowableWrapper t) {
|
catch (CacheOperationInvoker.ThrowableWrapper ex) {
|
||||||
Throwable ex = t.getOriginal();
|
Throwable original = ex.getOriginal();
|
||||||
if (!earlyRemove && operation.getExceptionTypeFilter().match(ex.getClass())) {
|
if (!earlyRemove && operation.getExceptionTypeFilter().match(original.getClass())) {
|
||||||
removeAll(context);
|
removeAll(context);
|
||||||
}
|
}
|
||||||
throw t;
|
throw ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import javax.cache.annotation.CacheMethodDetails;
|
import javax.cache.annotation.CacheMethodDetails;
|
||||||
import javax.cache.annotation.CacheRemoveAll;
|
import javax.cache.annotation.CacheRemoveAll;
|
||||||
|
|
@ -29,7 +29,7 @@ import org.springframework.util.ExceptionTypeFilter;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
* @see CacheRemoveAll
|
* @see CacheRemoveAll
|
||||||
*/
|
*/
|
||||||
public class CacheRemoveAllOperation extends BaseCacheOperation<CacheRemoveAll> {
|
class CacheRemoveAllOperation extends AbstractJCacheOperation<CacheRemoveAll> {
|
||||||
|
|
||||||
private final ExceptionTypeFilter exceptionTypeFilter;
|
private final ExceptionTypeFilter exceptionTypeFilter;
|
||||||
|
|
||||||
|
|
@ -22,7 +22,6 @@ import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||||
import org.springframework.cache.jcache.model.CacheRemoveOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercept methods annotated with {@link CacheRemove}.
|
* Intercept methods annotated with {@link CacheRemove}.
|
||||||
|
|
@ -31,7 +30,7 @@ import org.springframework.cache.jcache.model.CacheRemoveOperation;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class CacheRemoveEntryInterceptor extends AbstractKeyCacheInterceptor<CacheRemoveOperation, CacheRemove> {
|
class CacheRemoveEntryInterceptor extends AbstractKeyCacheInterceptor<CacheRemoveOperation, CacheRemove> {
|
||||||
|
|
||||||
protected CacheRemoveEntryInterceptor(CacheErrorHandler errorHandler) {
|
protected CacheRemoveEntryInterceptor(CacheErrorHandler errorHandler) {
|
||||||
super(errorHandler);
|
super(errorHandler);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import javax.cache.annotation.CacheMethodDetails;
|
import javax.cache.annotation.CacheMethodDetails;
|
||||||
import javax.cache.annotation.CacheRemove;
|
import javax.cache.annotation.CacheRemove;
|
||||||
|
|
@ -30,7 +30,7 @@ import org.springframework.util.ExceptionTypeFilter;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
* @see CacheRemove
|
* @see CacheRemove
|
||||||
*/
|
*/
|
||||||
public class CacheRemoveOperation extends BaseKeyCacheOperation<CacheRemove> {
|
class CacheRemoveOperation extends AbstractJCacheKeyOperation<CacheRemove> {
|
||||||
|
|
||||||
private final ExceptionTypeFilter exceptionTypeFilter;
|
private final ExceptionTypeFilter exceptionTypeFilter;
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ import org.springframework.util.Assert;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public class CacheResolverAdapter implements CacheResolver {
|
class CacheResolverAdapter implements CacheResolver {
|
||||||
|
|
||||||
private final javax.cache.annotation.CacheResolver target;
|
private final javax.cache.annotation.CacheResolver target;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,8 @@ import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||||
import org.springframework.cache.interceptor.CacheResolver;
|
import org.springframework.cache.interceptor.CacheResolver;
|
||||||
import org.springframework.cache.jcache.model.CacheResultOperation;
|
|
||||||
import org.springframework.util.SerializationUtils;
|
|
||||||
import org.springframework.util.ExceptionTypeFilter;
|
import org.springframework.util.ExceptionTypeFilter;
|
||||||
|
import org.springframework.util.SerializationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intercept methods annotated with {@link CacheResult}.
|
* Intercept methods annotated with {@link CacheResult}.
|
||||||
|
|
@ -34,7 +33,7 @@ import org.springframework.util.ExceptionTypeFilter;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class CacheResultInterceptor extends AbstractKeyCacheInterceptor<CacheResultOperation, CacheResult> {
|
class CacheResultInterceptor extends AbstractKeyCacheInterceptor<CacheResultOperation, CacheResult> {
|
||||||
|
|
||||||
public CacheResultInterceptor(CacheErrorHandler errorHandler) {
|
public CacheResultInterceptor(CacheErrorHandler errorHandler) {
|
||||||
super(errorHandler);
|
super(errorHandler);
|
||||||
|
|
@ -43,9 +42,9 @@ public class CacheResultInterceptor extends AbstractKeyCacheInterceptor<CacheRes
|
||||||
@Override
|
@Override
|
||||||
protected Object invoke(CacheOperationInvocationContext<CacheResultOperation> context,
|
protected Object invoke(CacheOperationInvocationContext<CacheResultOperation> context,
|
||||||
CacheOperationInvoker invoker) {
|
CacheOperationInvoker invoker) {
|
||||||
CacheResultOperation operation = context.getOperation();
|
|
||||||
|
|
||||||
final Object cacheKey = generateKey(context);
|
CacheResultOperation operation = context.getOperation();
|
||||||
|
Object cacheKey = generateKey(context);
|
||||||
|
|
||||||
Cache cache = resolveCache(context);
|
Cache cache = resolveCache(context);
|
||||||
Cache exceptionCache = resolveExceptionCache(context);
|
Cache exceptionCache = resolveExceptionCache(context);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import javax.cache.annotation.CacheMethodDetails;
|
import javax.cache.annotation.CacheMethodDetails;
|
||||||
import javax.cache.annotation.CacheResult;
|
import javax.cache.annotation.CacheResult;
|
||||||
|
|
@ -31,7 +31,7 @@ import org.springframework.util.StringUtils;
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
* @see CacheResult
|
* @see CacheResult
|
||||||
*/
|
*/
|
||||||
public class CacheResultOperation extends BaseKeyCacheOperation<CacheResult> {
|
class CacheResultOperation extends AbstractJCacheKeyOperation<CacheResult> {
|
||||||
|
|
||||||
private final ExceptionTypeFilter exceptionTypeFilter;
|
private final ExceptionTypeFilter exceptionTypeFilter;
|
||||||
|
|
||||||
|
|
@ -25,7 +25,6 @@ import javax.cache.annotation.CacheInvocationContext;
|
||||||
import javax.cache.annotation.CacheInvocationParameter;
|
import javax.cache.annotation.CacheInvocationParameter;
|
||||||
|
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.jcache.model.JCacheOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default {@link CacheOperationInvocationContext} implementation used
|
* The default {@link CacheOperationInvocationContext} implementation used
|
||||||
|
|
@ -35,7 +34,7 @@ import org.springframework.cache.jcache.model.JCacheOperation;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public class DefaultCacheInvocationContext<A extends Annotation>
|
class DefaultCacheInvocationContext<A extends Annotation>
|
||||||
implements CacheInvocationContext<A>, CacheOperationInvocationContext<JCacheOperation<A>> {
|
implements CacheInvocationContext<A>, CacheOperationInvocationContext<JCacheOperation<A>> {
|
||||||
|
|
||||||
private final JCacheOperation<A> operation;
|
private final JCacheOperation<A> operation;
|
||||||
|
|
@ -56,42 +55,42 @@ public class DefaultCacheInvocationContext<A extends Annotation>
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JCacheOperation<A> getOperation() {
|
public JCacheOperation<A> getOperation() {
|
||||||
return operation;
|
return this.operation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Method getMethod() {
|
public Method getMethod() {
|
||||||
return operation.getMethod();
|
return this.operation.getMethod();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] getArgs() {
|
public Object[] getArgs() {
|
||||||
return args.clone();
|
return this.args.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Annotation> getAnnotations() {
|
public Set<Annotation> getAnnotations() {
|
||||||
return operation.getAnnotations();
|
return this.operation.getAnnotations();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public A getCacheAnnotation() {
|
public A getCacheAnnotation() {
|
||||||
return operation.getCacheAnnotation();
|
return this.operation.getCacheAnnotation();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCacheName() {
|
public String getCacheName() {
|
||||||
return operation.getCacheName();
|
return this.operation.getCacheName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getTarget() {
|
public Object getTarget() {
|
||||||
return target;
|
return this.target;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CacheInvocationParameter[] getAllParameters() {
|
public CacheInvocationParameter[] getAllParameters() {
|
||||||
return allParameters.clone();
|
return this.allParameters.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -21,23 +21,20 @@ import java.lang.annotation.Annotation;
|
||||||
import javax.cache.annotation.CacheInvocationParameter;
|
import javax.cache.annotation.CacheInvocationParameter;
|
||||||
import javax.cache.annotation.CacheKeyInvocationContext;
|
import javax.cache.annotation.CacheKeyInvocationContext;
|
||||||
|
|
||||||
import org.springframework.cache.jcache.model.BaseKeyCacheOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CachePutOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default {@link CacheKeyInvocationContext} implementation.
|
* The default {@link CacheKeyInvocationContext} implementation.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public class DefaultCacheKeyInvocationContext<A extends Annotation>
|
class DefaultCacheKeyInvocationContext<A extends Annotation>
|
||||||
extends DefaultCacheInvocationContext<A> implements CacheKeyInvocationContext<A> {
|
extends DefaultCacheInvocationContext<A> implements CacheKeyInvocationContext<A> {
|
||||||
|
|
||||||
private final CacheInvocationParameter[] keyParameters;
|
private final CacheInvocationParameter[] keyParameters;
|
||||||
|
|
||||||
private final CacheInvocationParameter valueParameter;
|
private final CacheInvocationParameter valueParameter;
|
||||||
|
|
||||||
public DefaultCacheKeyInvocationContext(BaseKeyCacheOperation<A> operation,
|
public DefaultCacheKeyInvocationContext(AbstractJCacheKeyOperation<A> operation,
|
||||||
Object target, Object[] args) {
|
Object target, Object[] args) {
|
||||||
super(operation, target, args);
|
super(operation, target, args);
|
||||||
this.keyParameters = operation.getKeyParameters(args);
|
this.keyParameters = operation.getKeyParameters(args);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import static java.util.Arrays.*;
|
import static java.util.Arrays.*;
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ import javax.cache.annotation.CacheMethodDetails;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public class DefaultCacheMethodDetails<A extends Annotation> implements CacheMethodDetails<A> {
|
class DefaultCacheMethodDetails<A extends Annotation> implements CacheMethodDetails<A> {
|
||||||
|
|
||||||
private final Method method;
|
private final Method method;
|
||||||
|
|
||||||
|
|
@ -42,8 +42,8 @@ public class DefaultCacheMethodDetails<A extends Annotation> implements CacheMet
|
||||||
|
|
||||||
private final String cacheName;
|
private final String cacheName;
|
||||||
|
|
||||||
public DefaultCacheMethodDetails(Method method, A cacheAnnotation,
|
|
||||||
String cacheName) {
|
public DefaultCacheMethodDetails(Method method, A cacheAnnotation, String cacheName) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.annotations = Collections.unmodifiableSet(
|
this.annotations = Collections.unmodifiableSet(
|
||||||
new LinkedHashSet<Annotation>(asList(method.getAnnotations())));
|
new LinkedHashSet<Annotation>(asList(method.getAnnotations())));
|
||||||
|
|
@ -51,32 +51,33 @@ public class DefaultCacheMethodDetails<A extends Annotation> implements CacheMet
|
||||||
this.cacheName = cacheName;
|
this.cacheName = cacheName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Method getMethod() {
|
public Method getMethod() {
|
||||||
return method;
|
return this.method;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Annotation> getAnnotations() {
|
public Set<Annotation> getAnnotations() {
|
||||||
return annotations;
|
return this.annotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public A getCacheAnnotation() {
|
public A getCacheAnnotation() {
|
||||||
return cacheAnnotation;
|
return this.cacheAnnotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getCacheName() {
|
public String getCacheName() {
|
||||||
return cacheName;
|
return this.cacheName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder sb = new StringBuilder("details[");
|
StringBuilder sb = new StringBuilder("CacheMethodDetails[");
|
||||||
sb.append("method=").append(method);
|
sb.append("method=").append(this.method);
|
||||||
sb.append(", cacheAnnotation=").append(cacheAnnotation);
|
sb.append(", cacheAnnotation=").append(this.cacheAnnotation);
|
||||||
sb.append(", cacheName='").append(cacheName).append('\'');
|
sb.append(", cacheName='").append(this.cacheName).append('\'');
|
||||||
sb.append(']');
|
sb.append(']');
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
@ -25,6 +25,7 @@ import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.cache.interceptor.CacheResolver;
|
import org.springframework.cache.interceptor.CacheResolver;
|
||||||
import org.springframework.cache.interceptor.KeyGenerator;
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
import org.springframework.cache.interceptor.SimpleCacheResolver;
|
import org.springframework.cache.interceptor.SimpleCacheResolver;
|
||||||
|
import org.springframework.cache.interceptor.SimpleKeyGenerator;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
import org.springframework.context.ApplicationContextAware;
|
import org.springframework.context.ApplicationContextAware;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
@ -37,12 +38,14 @@ import org.springframework.util.Assert;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource
|
public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSource
|
||||||
implements InitializingBean, ApplicationContextAware {
|
implements InitializingBean, ApplicationContextAware {
|
||||||
|
|
||||||
private CacheManager cacheManager;
|
private CacheManager cacheManager;
|
||||||
|
|
||||||
private KeyGenerator keyGenerator;
|
private KeyGenerator keyGenerator = new SimpleKeyGenerator();
|
||||||
|
|
||||||
|
private KeyGenerator adaptedKeyGenerator;
|
||||||
|
|
||||||
private CacheResolver cacheResolver;
|
private CacheResolver cacheResolver;
|
||||||
|
|
||||||
|
|
@ -50,23 +53,6 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource
|
||||||
|
|
||||||
private ApplicationContext applicationContext;
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterPropertiesSet() {
|
|
||||||
Assert.state((cacheResolver != null && exceptionCacheResolver != null)
|
|
||||||
|| cacheManager != null, "'cacheManager' is required if cache resolvers are not set.");
|
|
||||||
Assert.state(this.applicationContext != null, "The application context was not injected as it should.");
|
|
||||||
|
|
||||||
if (keyGenerator == null) {
|
|
||||||
keyGenerator = new KeyGeneratorAdapter(this, new SimpleCacheKeyGenerator());
|
|
||||||
}
|
|
||||||
if (cacheResolver == null) {
|
|
||||||
cacheResolver = new SimpleCacheResolver(cacheManager);
|
|
||||||
}
|
|
||||||
if (exceptionCacheResolver == null) {
|
|
||||||
exceptionCacheResolver = new SimpleExceptionCacheResolver(cacheManager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the default {@link CacheManager} to use to lookup cache by name. Only mandatory
|
* Set the default {@link CacheManager} to use to lookup cache by name. Only mandatory
|
||||||
* if the {@linkplain CacheResolver cache resolvers} have not been set.
|
* if the {@linkplain CacheResolver cache resolvers} have not been set.
|
||||||
|
|
@ -76,13 +62,18 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the default {@link KeyGenerator}. If none is set, a default JSR-107 compliant
|
* Set the default {@link KeyGenerator}. If none is set, a {@link SimpleKeyGenerator}
|
||||||
* key generator is used.
|
* honoringKe the JSR-107 {@link javax.cache.annotation.CacheKey} and
|
||||||
|
* {@link javax.cache.annotation.CacheValue} will be used.
|
||||||
*/
|
*/
|
||||||
public void setKeyGenerator(KeyGenerator keyGenerator) {
|
public void setKeyGenerator(KeyGenerator keyGenerator) {
|
||||||
this.keyGenerator = keyGenerator;
|
this.keyGenerator = keyGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public KeyGenerator getKeyGenerator() {
|
||||||
|
return this.keyGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the {@link CacheResolver} to resolve regular caches. If none is set, a default
|
* Set the {@link CacheResolver} to resolve regular caches. If none is set, a default
|
||||||
* implementation using the specified cache manager will be used.
|
* implementation using the specified cache manager will be used.
|
||||||
|
|
@ -91,6 +82,10 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource
|
||||||
this.cacheResolver = cacheResolver;
|
this.cacheResolver = cacheResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CacheResolver getCacheResolver() {
|
||||||
|
return this.cacheResolver;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the {@link CacheResolver} to resolve exception caches. If none is set, a default
|
* Set the {@link CacheResolver} to resolve exception caches. If none is set, a default
|
||||||
* implementation using the specified cache manager will be used.
|
* implementation using the specified cache manager will be used.
|
||||||
|
|
@ -99,14 +94,33 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource
|
||||||
this.exceptionCacheResolver = exceptionCacheResolver;
|
this.exceptionCacheResolver = exceptionCacheResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CacheResolver getExceptionCacheResolver() {
|
||||||
|
return this.exceptionCacheResolver;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setApplicationContext(ApplicationContext applicationContext) {
|
public void setApplicationContext(ApplicationContext applicationContext) {
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterPropertiesSet() {
|
||||||
|
Assert.state((this.cacheResolver != null && this.exceptionCacheResolver != null)
|
||||||
|
|| this.cacheManager != null, "'cacheManager' is required if cache resolvers are not set.");
|
||||||
|
Assert.state(this.applicationContext != null, "The application context was not injected as it should.");
|
||||||
|
|
||||||
|
this.adaptedKeyGenerator = new KeyGeneratorAdapter(this, this.keyGenerator);
|
||||||
|
if (this.cacheResolver == null) {
|
||||||
|
this.cacheResolver = new SimpleCacheResolver(this.cacheManager);
|
||||||
|
}
|
||||||
|
if (this.exceptionCacheResolver == null) {
|
||||||
|
this.exceptionCacheResolver = new SimpleExceptionCacheResolver(this.cacheManager);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected <T> T getBean(Class<T> type) {
|
protected <T> T getBean(Class<T> type) {
|
||||||
Map<String, T> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, type);
|
Map<String, T> map = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.applicationContext, type);
|
||||||
if (map.size() == 1) {
|
if (map.size() == 1) {
|
||||||
return map.values().iterator().next();
|
return map.values().iterator().next();
|
||||||
}
|
}
|
||||||
|
|
@ -116,18 +130,18 @@ public class DefaultJCacheOperationSource extends AnnotationCacheOperationSource
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CacheResolver getDefaultCacheResolver() {
|
protected CacheResolver getDefaultCacheResolver() {
|
||||||
return cacheResolver;
|
return this.cacheResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CacheResolver getDefaultExceptionCacheResolver() {
|
protected CacheResolver getDefaultExceptionCacheResolver() {
|
||||||
return exceptionCacheResolver;
|
return this.exceptionCacheResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyGenerator getDefaultKeyGenerator() {
|
protected KeyGenerator getDefaultKeyGenerator() {
|
||||||
return keyGenerator;
|
return this.adaptedKeyGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,9 @@ import org.apache.commons.logging.LogFactory;
|
||||||
import org.springframework.aop.framework.AopProxyUtils;
|
import org.springframework.aop.framework.AopProxyUtils;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.cache.interceptor.AbstractCacheInvoker;
|
import org.springframework.cache.interceptor.AbstractCacheInvoker;
|
||||||
import org.springframework.cache.interceptor.BasicCacheOperation;
|
import org.springframework.cache.interceptor.BasicOperation;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||||
import org.springframework.cache.jcache.model.CachePutOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CacheRemoveAllOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CacheRemoveOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CacheResultOperation;
|
|
||||||
import org.springframework.cache.jcache.model.JCacheOperation;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -134,7 +129,7 @@ public class JCacheAspectSupport extends AbstractCacheInvoker implements Initial
|
||||||
|
|
||||||
CacheOperationInvoker adapter = new CacheOperationInvokerAdapter(invoker);
|
CacheOperationInvoker adapter = new CacheOperationInvokerAdapter(invoker);
|
||||||
|
|
||||||
BasicCacheOperation operation = context.getOperation();
|
BasicOperation operation = context.getOperation();
|
||||||
if (operation instanceof CacheResultOperation) {
|
if (operation instanceof CacheResultOperation) {
|
||||||
return cacheResultInterceptor.invoke(
|
return cacheResultInterceptor.invoke(
|
||||||
(CacheOperationInvocationContext<CacheResultOperation>) context, adapter);
|
(CacheOperationInvocationContext<CacheResultOperation>) context, adapter);
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,11 @@ import org.springframework.cache.interceptor.CacheOperationInvoker;
|
||||||
* <p>JCacheInterceptors are thread-safe.
|
* <p>JCacheInterceptors are thread-safe.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
|
* @since 4.1
|
||||||
* @see org.springframework.cache.interceptor.CacheInterceptor
|
* @see org.springframework.cache.interceptor.CacheInterceptor
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class JCacheInterceptor extends JCacheAspectSupport
|
public class JCacheInterceptor extends JCacheAspectSupport implements MethodInterceptor, Serializable {
|
||||||
implements MethodInterceptor, Serializable {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
public Object invoke(final MethodInvocation invocation) throws Throwable {
|
||||||
|
|
|
||||||
|
|
@ -14,14 +14,14 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
|
|
||||||
import javax.cache.annotation.CacheInvocationParameter;
|
import javax.cache.annotation.CacheInvocationParameter;
|
||||||
import javax.cache.annotation.CacheMethodDetails;
|
import javax.cache.annotation.CacheMethodDetails;
|
||||||
|
|
||||||
import org.springframework.cache.interceptor.BasicCacheOperation;
|
import org.springframework.cache.interceptor.BasicOperation;
|
||||||
import org.springframework.cache.interceptor.CacheResolver;
|
import org.springframework.cache.interceptor.CacheResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -33,8 +33,7 @@ import org.springframework.cache.interceptor.CacheResolver;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public interface JCacheOperation<A extends Annotation>
|
public interface JCacheOperation<A extends Annotation> extends BasicOperation, CacheMethodDetails<A> {
|
||||||
extends CacheMethodDetails<A>, BasicCacheOperation {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the {@link CacheResolver} instance to use to resolve the cache to
|
* Return the {@link CacheResolver} instance to use to resolve the cache to
|
||||||
|
|
@ -18,8 +18,6 @@ package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.springframework.cache.jcache.model.JCacheOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface used by {@link JCacheInterceptor}. Implementations know how to source
|
* Interface used by {@link JCacheInterceptor}. Implementations know how to source
|
||||||
* cache operation attributes from standard JSR-107 annotations.
|
* cache operation attributes from standard JSR-107 annotations.
|
||||||
|
|
|
||||||
|
|
@ -2,58 +2,103 @@ package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.cache.annotation.CacheInvocationParameter;
|
||||||
import javax.cache.annotation.CacheKeyGenerator;
|
import javax.cache.annotation.CacheKeyGenerator;
|
||||||
import javax.cache.annotation.CacheKeyInvocationContext;
|
import javax.cache.annotation.CacheKeyInvocationContext;
|
||||||
|
|
||||||
import org.springframework.cache.interceptor.KeyGenerator;
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
import org.springframework.cache.jcache.model.BaseKeyCacheOperation;
|
|
||||||
import org.springframework.cache.jcache.model.JCacheOperation;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring's {@link KeyGenerator} implementation that delegates to a standard
|
* Spring's {@link KeyGenerator} implementation that either delegates to a
|
||||||
* JSR-107 {@link javax.cache.annotation.CacheKeyGenerator}.
|
* standard JSR-107 {@link javax.cache.annotation.CacheKeyGenerator}, or
|
||||||
* <p>Used internally to invoke user-based JSR-107 cache key generators.
|
* wrap a standard {@link KeyGenerator} so that only relevant parameters
|
||||||
|
* are handled.
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public class KeyGeneratorAdapter implements KeyGenerator {
|
class KeyGeneratorAdapter implements KeyGenerator {
|
||||||
|
|
||||||
private final JCacheOperationSource cacheOperationSource;
|
private final JCacheOperationSource cacheOperationSource;
|
||||||
|
|
||||||
private final CacheKeyGenerator target;
|
private KeyGenerator keyGenerator;
|
||||||
|
|
||||||
public KeyGeneratorAdapter(JCacheOperationSource cacheOperationSource, CacheKeyGenerator target) {
|
private CacheKeyGenerator cacheKeyGenerator;
|
||||||
Assert.notNull(cacheOperationSource, "cacheOperationSource must be set.");
|
|
||||||
Assert.notNull(target, "cache key generator must be set.");
|
/**
|
||||||
|
* Create an instance with the given {@link KeyGenerator} so that {@link javax.cache.annotation.CacheKey}
|
||||||
|
* and {@link javax.cache.annotation.CacheValue} are handled according to the spec.
|
||||||
|
*/
|
||||||
|
public KeyGeneratorAdapter(JCacheOperationSource cacheOperationSource, KeyGenerator target) {
|
||||||
|
Assert.notNull(cacheOperationSource, "cacheOperationSource must not be null.");
|
||||||
|
Assert.notNull(target, "KeyGenerator must not be null");
|
||||||
this.cacheOperationSource = cacheOperationSource;
|
this.cacheOperationSource = cacheOperationSource;
|
||||||
this.target = target;
|
this.keyGenerator = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the underlying {@link CacheKeyGenerator} that this instance is using.
|
* Create an instance used to wrap the specified {@link javax.cache.annotation.CacheKeyGenerator}.
|
||||||
*/
|
*/
|
||||||
protected CacheKeyGenerator getTarget() {
|
public KeyGeneratorAdapter(JCacheOperationSource cacheOperationSource, CacheKeyGenerator target) {
|
||||||
return target;
|
Assert.notNull(cacheOperationSource, "cacheOperationSource must not be null.");
|
||||||
|
Assert.notNull(target, "KeyGenerator must not be null");
|
||||||
|
this.cacheOperationSource = cacheOperationSource;
|
||||||
|
this.cacheKeyGenerator = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the target key generator to use in the form of either a {@link KeyGenerator}
|
||||||
|
* or a {@link CacheKeyGenerator}.
|
||||||
|
*/
|
||||||
|
public Object getTarget() {
|
||||||
|
return (this.keyGenerator != null ? this.keyGenerator : this.cacheKeyGenerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object generate(Object target, Method method, Object... params) {
|
public Object generate(Object target, Method method, Object... params) {
|
||||||
JCacheOperation<?> operation = cacheOperationSource.getCacheOperation(method, target.getClass());
|
JCacheOperation<?> operation = this.cacheOperationSource.getCacheOperation(method, target.getClass());
|
||||||
if (!(BaseKeyCacheOperation.class.isInstance(operation))) {
|
if (!(AbstractJCacheKeyOperation.class.isInstance(operation))) {
|
||||||
throw new IllegalStateException("Invalid operation, should be a key-based operation " + operation);
|
throw new IllegalStateException("Invalid operation, should be a key-based operation " + operation);
|
||||||
}
|
}
|
||||||
CacheKeyInvocationContext<?> invocationContext = createCacheKeyInvocationContext(target, operation, params);
|
CacheKeyInvocationContext<?> invocationContext = createCacheKeyInvocationContext(target, operation, params);
|
||||||
|
|
||||||
return this.target.generateCacheKey(invocationContext);
|
if (this.cacheKeyGenerator != null) {
|
||||||
|
return this.cacheKeyGenerator.generateCacheKey(invocationContext);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return doGenerate(this.keyGenerator, invocationContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private static Object doGenerate(KeyGenerator keyGenerator, CacheKeyInvocationContext<?> context) {
|
||||||
|
List<Object> parameters = new ArrayList<Object>();
|
||||||
|
for (CacheInvocationParameter param : context.getKeyParameters()) {
|
||||||
|
Object value = param.getValue();
|
||||||
|
if (param.getParameterPosition() == context.getAllParameters().length - 1 &&
|
||||||
|
context.getMethod().isVarArgs()) {
|
||||||
|
parameters.addAll((List<Object>) CollectionUtils.arrayToList(value));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
parameters.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return keyGenerator.generate(context.getTarget(), context.getMethod(),
|
||||||
|
parameters.toArray(new Object[parameters.size()]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private CacheKeyInvocationContext<?> createCacheKeyInvocationContext(Object target,
|
private CacheKeyInvocationContext<?> createCacheKeyInvocationContext(Object target,
|
||||||
JCacheOperation<?> operation, Object[] params) {
|
JCacheOperation<?> operation, Object[] params) {
|
||||||
BaseKeyCacheOperation<Annotation> keyCacheOperation = (BaseKeyCacheOperation<Annotation>) operation;
|
AbstractJCacheKeyOperation<Annotation> keyCacheOperation = (AbstractJCacheKeyOperation<Annotation>) operation;
|
||||||
return new DefaultCacheKeyInvocationContext<Annotation>(keyCacheOperation, target, params);
|
return new DefaultCacheKeyInvocationContext<Annotation>(keyCacheOperation, target, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2014 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.springframework.cache.jcache.interceptor;
|
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
|
|
||||||
import javax.cache.annotation.CacheInvocationParameter;
|
|
||||||
import javax.cache.annotation.CacheKeyGenerator;
|
|
||||||
import javax.cache.annotation.CacheKeyInvocationContext;
|
|
||||||
import javax.cache.annotation.GeneratedCacheKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A JSR-107 compliant key generator. Uses only the parameters that have been annotated
|
|
||||||
* with {@link javax.cache.annotation.CacheKey} or all of them if none are set, except
|
|
||||||
* the {@link javax.cache.annotation.CacheValue} one.
|
|
||||||
*
|
|
||||||
* @author Stephane Nicoll
|
|
||||||
* @since 4.1
|
|
||||||
* @see javax.cache.annotation.CacheKeyInvocationContext#getKeyParameters()
|
|
||||||
*/
|
|
||||||
public class SimpleCacheKeyGenerator implements CacheKeyGenerator {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public GeneratedCacheKey generateCacheKey(CacheKeyInvocationContext<? extends Annotation> context) {
|
|
||||||
CacheInvocationParameter[] keyParameters = context.getKeyParameters();
|
|
||||||
final Object[] parameters = new Object[keyParameters.length];
|
|
||||||
for (int i = 0; i < keyParameters.length; i++) {
|
|
||||||
parameters[i] = keyParameters[i].getValue();
|
|
||||||
}
|
|
||||||
return new SimpleGeneratedCacheKey(parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -20,11 +20,10 @@ import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.cache.interceptor.BaseCacheResolver;
|
import org.springframework.cache.interceptor.AbstractCacheResolver;
|
||||||
import org.springframework.cache.interceptor.BasicCacheOperation;
|
import org.springframework.cache.interceptor.BasicOperation;
|
||||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.interceptor.CacheResolver;
|
import org.springframework.cache.interceptor.CacheResolver;
|
||||||
import org.springframework.cache.jcache.model.CacheResultOperation;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link CacheResolver} that resolves the exception cache
|
* A simple {@link CacheResolver} that resolves the exception cache
|
||||||
|
|
@ -33,9 +32,9 @@ import org.springframework.cache.jcache.model.CacheResultOperation;
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
* @see org.springframework.cache.jcache.model.CacheResultOperation#getExceptionCacheName()
|
* @see CacheResultOperation#getExceptionCacheName()
|
||||||
*/
|
*/
|
||||||
public class SimpleExceptionCacheResolver extends BaseCacheResolver {
|
public class SimpleExceptionCacheResolver extends AbstractCacheResolver {
|
||||||
|
|
||||||
public SimpleExceptionCacheResolver(CacheManager cacheManager) {
|
public SimpleExceptionCacheResolver(CacheManager cacheManager) {
|
||||||
super(cacheManager);
|
super(cacheManager);
|
||||||
|
|
@ -43,7 +42,7 @@ public class SimpleExceptionCacheResolver extends BaseCacheResolver {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
|
protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
|
||||||
BasicCacheOperation operation = context.getOperation();
|
BasicOperation operation = context.getOperation();
|
||||||
if (!(operation instanceof CacheResultOperation)) {
|
if (!(operation instanceof CacheResultOperation)) {
|
||||||
throw new IllegalStateException("Could not extract exception cache name from " + operation);
|
throw new IllegalStateException("Could not extract exception cache name from " + operation);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
package org.springframework.cache.jcache.interceptor;
|
|
||||||
|
|
||||||
import javax.cache.annotation.GeneratedCacheKey;
|
|
||||||
|
|
||||||
import org.springframework.cache.interceptor.SimpleKey;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A {@link SimpleKey} that implements the {@link GeneratedCacheKey} contract
|
|
||||||
* required by JSR-107
|
|
||||||
*
|
|
||||||
* @author Stephane Nicoll
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("serial")
|
|
||||||
public final class SimpleGeneratedCacheKey extends SimpleKey implements GeneratedCacheKey {
|
|
||||||
|
|
||||||
public SimpleGeneratedCacheKey(Object... elements) {
|
|
||||||
super(elements);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
/**
|
|
||||||
* Resolved model of JSR-107 cache annotations. Used internally by the interceptors
|
|
||||||
* in org.springframework.cache.jcache.interceptor.
|
|
||||||
*/
|
|
||||||
package org.springframework.cache.jcache.model;
|
|
||||||
|
|
@ -28,7 +28,7 @@ import org.junit.rules.TestName;
|
||||||
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.cache.jcache.interceptor.SimpleGeneratedCacheKey;
|
import org.springframework.cache.interceptor.SimpleKeyGenerator;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -523,7 +523,7 @@ public abstract class AbstractJCacheAnnotationTests {
|
||||||
|
|
||||||
|
|
||||||
private Object createKey(Object... params) {
|
private Object createKey(Object... params) {
|
||||||
return new SimpleGeneratedCacheKey(params);
|
return SimpleKeyGenerator.generateKey(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Cache getCache(String name) {
|
private Cache getCache(String name) {
|
||||||
|
|
|
||||||
|
|
@ -61,11 +61,11 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
|
||||||
AnnotationConfigApplicationContext context =
|
AnnotationConfigApplicationContext context =
|
||||||
new AnnotationConfigApplicationContext(FullCachingConfig.class);
|
new AnnotationConfigApplicationContext(FullCachingConfig.class);
|
||||||
DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class);
|
DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class);
|
||||||
assertSame(context.getBean(KeyGenerator.class), cos.getDefaultKeyGenerator());
|
assertSame(context.getBean(KeyGenerator.class), cos.getKeyGenerator());
|
||||||
assertSame(context.getBean("cacheResolver", CacheResolver.class),
|
assertSame(context.getBean("cacheResolver", CacheResolver.class),
|
||||||
cos.getDefaultCacheResolver());
|
cos.getCacheResolver());
|
||||||
assertSame(context.getBean("exceptionCacheResolver", CacheResolver.class),
|
assertSame(context.getBean("exceptionCacheResolver", CacheResolver.class),
|
||||||
cos.getDefaultExceptionCacheResolver());
|
cos.getExceptionCacheResolver());
|
||||||
JCacheInterceptor interceptor = context.getBean(JCacheInterceptor.class);
|
JCacheInterceptor interceptor = context.getBean(JCacheInterceptor.class);
|
||||||
assertSame(context.getBean("errorHandler", CacheErrorHandler.class), interceptor.getErrorHandler());
|
assertSame(context.getBean("errorHandler", CacheErrorHandler.class), interceptor.getErrorHandler());
|
||||||
}
|
}
|
||||||
|
|
@ -76,14 +76,14 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
|
||||||
new AnnotationConfigApplicationContext(EmptyConfigSupportConfig.class);
|
new AnnotationConfigApplicationContext(EmptyConfigSupportConfig.class);
|
||||||
|
|
||||||
DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class);
|
DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class);
|
||||||
assertNotNull(cos.getDefaultCacheResolver());
|
assertNotNull(cos.getCacheResolver());
|
||||||
assertEquals(SimpleCacheResolver.class, cos.getDefaultCacheResolver().getClass());
|
assertEquals(SimpleCacheResolver.class, cos.getCacheResolver().getClass());
|
||||||
assertSame(context.getBean(CacheManager.class),
|
assertSame(context.getBean(CacheManager.class),
|
||||||
((SimpleCacheResolver) cos.getDefaultCacheResolver()).getCacheManager());
|
((SimpleCacheResolver) cos.getCacheResolver()).getCacheManager());
|
||||||
assertNotNull(cos.getDefaultExceptionCacheResolver());
|
assertNotNull(cos.getExceptionCacheResolver());
|
||||||
assertEquals(SimpleExceptionCacheResolver.class, cos.getDefaultExceptionCacheResolver().getClass());
|
assertEquals(SimpleExceptionCacheResolver.class, cos.getExceptionCacheResolver().getClass());
|
||||||
assertSame(context.getBean(CacheManager.class),
|
assertSame(context.getBean(CacheManager.class),
|
||||||
((SimpleExceptionCacheResolver) cos.getDefaultExceptionCacheResolver()).getCacheManager());
|
((SimpleExceptionCacheResolver) cos.getExceptionCacheResolver()).getCacheManager());
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,9 +93,9 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
|
||||||
new AnnotationConfigApplicationContext(FullCachingConfigSupport.class);
|
new AnnotationConfigApplicationContext(FullCachingConfigSupport.class);
|
||||||
|
|
||||||
DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class);
|
DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class);
|
||||||
assertSame(context.getBean("cacheResolver"), cos.getDefaultCacheResolver());
|
assertSame(context.getBean("cacheResolver"), cos.getCacheResolver());
|
||||||
assertSame(context.getBean("keyGenerator"), cos.getDefaultKeyGenerator());
|
assertSame(context.getBean("keyGenerator"), cos.getKeyGenerator());
|
||||||
assertSame(context.getBean("exceptionCacheResolver"), cos.getDefaultExceptionCacheResolver());
|
assertSame(context.getBean("exceptionCacheResolver"), cos.getExceptionCacheResolver());
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ public class JCacheNamespaceDrivenTests extends AbstractJCacheAnnotationTests {
|
||||||
"/org/springframework/cache/jcache/config/jCacheNamespaceDriven-resolver.xml");
|
"/org/springframework/cache/jcache/config/jCacheNamespaceDriven-resolver.xml");
|
||||||
|
|
||||||
DefaultJCacheOperationSource ci = context.getBean(DefaultJCacheOperationSource.class);
|
DefaultJCacheOperationSource ci = context.getBean(DefaultJCacheOperationSource.class);
|
||||||
assertSame(context.getBean("cacheResolver"), ci.getDefaultCacheResolver());
|
assertSame(context.getBean("cacheResolver"), ci.getCacheResolver());
|
||||||
context.close();
|
context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
|
@ -29,6 +29,7 @@ import javax.cache.annotation.CacheResult;
|
||||||
import javax.cache.annotation.CacheValue;
|
import javax.cache.annotation.CacheValue;
|
||||||
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.cache.interceptor.SimpleKeyGenerator;
|
||||||
import org.springframework.cache.jcache.config.JCacheableService;
|
import org.springframework.cache.jcache.config.JCacheableService;
|
||||||
import org.springframework.cache.jcache.support.TestableCacheKeyGenerator;
|
import org.springframework.cache.jcache.support.TestableCacheKeyGenerator;
|
||||||
import org.springframework.cache.jcache.support.TestableCacheResolverFactory;
|
import org.springframework.cache.jcache.support.TestableCacheResolverFactory;
|
||||||
|
|
@ -109,7 +110,7 @@ public class AnnotatedJCacheableService implements JCacheableService<Long> {
|
||||||
@Override
|
@Override
|
||||||
@CachePut(afterInvocation = false)
|
@CachePut(afterInvocation = false)
|
||||||
public void earlyPut(String id, @CacheValue Object value) {
|
public void earlyPut(String id, @CacheValue Object value) {
|
||||||
SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(id);
|
Object key = SimpleKeyGenerator.generateKey(id);
|
||||||
Cache.ValueWrapper valueWrapper = defaultCache.get(key);
|
Cache.ValueWrapper valueWrapper = defaultCache.get(key);
|
||||||
if (valueWrapper == null) {
|
if (valueWrapper == null) {
|
||||||
throw new AssertionError("Excepted value to be put in cache with key " + key);
|
throw new AssertionError("Excepted value to be put in cache with key " + key);
|
||||||
|
|
@ -141,7 +142,7 @@ public class AnnotatedJCacheableService implements JCacheableService<Long> {
|
||||||
@Override
|
@Override
|
||||||
@CacheRemove(afterInvocation = false)
|
@CacheRemove(afterInvocation = false)
|
||||||
public void earlyRemove(String id) {
|
public void earlyRemove(String id) {
|
||||||
SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(id);
|
Object key = SimpleKeyGenerator.generateKey(id);
|
||||||
Cache.ValueWrapper valueWrapper = defaultCache.get(key);
|
Cache.ValueWrapper valueWrapper = defaultCache.get(key);
|
||||||
if (valueWrapper != null) {
|
if (valueWrapper != null) {
|
||||||
throw new AssertionError("Value with key " + key + " expected to be already remove from cache");
|
throw new AssertionError("Value with key " + key + " expected to be already remove from cache");
|
||||||
|
|
|
||||||
|
|
@ -34,12 +34,6 @@ import org.junit.Test;
|
||||||
import org.springframework.cache.interceptor.CacheResolver;
|
import org.springframework.cache.interceptor.CacheResolver;
|
||||||
import org.springframework.cache.interceptor.KeyGenerator;
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
import org.springframework.cache.jcache.AbstractJCacheTests;
|
import org.springframework.cache.jcache.AbstractJCacheTests;
|
||||||
import org.springframework.cache.jcache.model.BaseKeyCacheOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CachePutOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CacheRemoveAllOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CacheRemoveOperation;
|
|
||||||
import org.springframework.cache.jcache.model.CacheResultOperation;
|
|
||||||
import org.springframework.cache.jcache.model.JCacheOperation;
|
|
||||||
import org.springframework.cache.jcache.support.TestableCacheKeyGenerator;
|
import org.springframework.cache.jcache.support.TestableCacheKeyGenerator;
|
||||||
import org.springframework.cache.jcache.support.TestableCacheResolver;
|
import org.springframework.cache.jcache.support.TestableCacheResolver;
|
||||||
import org.springframework.cache.jcache.support.TestableCacheResolverFactory;
|
import org.springframework.cache.jcache.support.TestableCacheResolverFactory;
|
||||||
|
|
@ -142,7 +136,8 @@ public class AnnotationCacheOperationSourceTests extends AbstractJCacheTests {
|
||||||
getCacheOperation(CacheResultOperation.class, CustomService.class, name.getMethodName(), Long.class);
|
getCacheOperation(CacheResultOperation.class, CustomService.class, name.getMethodName(), Long.class);
|
||||||
assertJCacheResolver(operation.getCacheResolver(), TestableCacheResolver.class);
|
assertJCacheResolver(operation.getCacheResolver(), TestableCacheResolver.class);
|
||||||
assertJCacheResolver(operation.getExceptionCacheResolver(), null);
|
assertJCacheResolver(operation.getExceptionCacheResolver(), null);
|
||||||
assertEquals(defaultKeyGenerator, operation.getKeyGenerator());
|
assertEquals(KeyGeneratorAdapter.class, operation.getKeyGenerator().getClass());
|
||||||
|
assertEquals(defaultKeyGenerator, ((KeyGeneratorAdapter) operation.getKeyGenerator()).getTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -184,9 +179,10 @@ public class AnnotationCacheOperationSourceTests extends AbstractJCacheTests {
|
||||||
assertCacheKeyGenerator(operation.getKeyGenerator(), TestableCacheKeyGenerator.class);
|
assertCacheKeyGenerator(operation.getKeyGenerator(), TestableCacheKeyGenerator.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertDefaults(BaseKeyCacheOperation<?> operation) {
|
private void assertDefaults(AbstractJCacheKeyOperation<?> operation) {
|
||||||
assertEquals(defaultCacheResolver, operation.getCacheResolver());
|
assertEquals(defaultCacheResolver, operation.getCacheResolver());
|
||||||
assertEquals(defaultKeyGenerator, operation.getKeyGenerator());
|
assertEquals(KeyGeneratorAdapter.class, operation.getKeyGenerator().getClass());
|
||||||
|
assertEquals(defaultKeyGenerator, ((KeyGeneratorAdapter) operation.getKeyGenerator()).getTarget());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected <T extends JCacheOperation<?>> T getDefaultCacheOperation(Class<T> operationType, Class<?>... parameterTypes) {
|
protected <T extends JCacheOperation<?>> T getDefaultCacheOperation(Class<T> operationType, Class<?>... parameterTypes) {
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
|
@ -34,8 +34,6 @@ import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
import org.springframework.cache.Cache;
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.jcache.AbstractJCacheTests;
|
import org.springframework.cache.jcache.AbstractJCacheTests;
|
||||||
import org.springframework.cache.jcache.model.CacheResultOperation;
|
|
||||||
import org.springframework.cache.jcache.model.DefaultCacheMethodDetails;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
|
@ -40,6 +40,7 @@ import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||||
|
import org.springframework.cache.interceptor.SimpleKeyGenerator;
|
||||||
import org.springframework.cache.jcache.config.JCacheConfigurerSupport;
|
import org.springframework.cache.jcache.config.JCacheConfigurerSupport;
|
||||||
import org.springframework.cache.support.SimpleCacheManager;
|
import org.springframework.cache.support.SimpleCacheManager;
|
||||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
|
@ -72,7 +73,7 @@ public class JCacheErrorHandlerTests {
|
||||||
@Test
|
@Test
|
||||||
public void getFail() {
|
public void getFail() {
|
||||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on get");
|
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on get");
|
||||||
SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(0L);
|
Object key = SimpleKeyGenerator.generateKey(0L);
|
||||||
doThrow(exception).when(cache).get(key);
|
doThrow(exception).when(cache).get(key);
|
||||||
|
|
||||||
this.simpleService.get(0L);
|
this.simpleService.get(0L);
|
||||||
|
|
@ -82,7 +83,7 @@ public class JCacheErrorHandlerTests {
|
||||||
@Test
|
@Test
|
||||||
public void putFail() {
|
public void putFail() {
|
||||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on put");
|
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on put");
|
||||||
SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(0L);
|
Object key = SimpleKeyGenerator.generateKey(0L);
|
||||||
doThrow(exception).when(cache).put(key, 234L);
|
doThrow(exception).when(cache).put(key, 234L);
|
||||||
|
|
||||||
this.simpleService.put(0L, 234L);
|
this.simpleService.put(0L, 234L);
|
||||||
|
|
@ -92,7 +93,7 @@ public class JCacheErrorHandlerTests {
|
||||||
@Test
|
@Test
|
||||||
public void evictFail() {
|
public void evictFail() {
|
||||||
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on evict");
|
UnsupportedOperationException exception = new UnsupportedOperationException("Test exception on evict");
|
||||||
SimpleGeneratedCacheKey key = new SimpleGeneratedCacheKey(0L);
|
Object key = SimpleKeyGenerator.generateKey(0L);
|
||||||
doThrow(exception).when(cache).evict(key);
|
doThrow(exception).when(cache).evict(key);
|
||||||
|
|
||||||
this.simpleService.evict(0L);
|
this.simpleService.evict(0L);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
|
|
||||||
|
import javax.cache.annotation.CacheDefaults;
|
||||||
|
import javax.cache.annotation.CacheKey;
|
||||||
|
import javax.cache.annotation.CacheResult;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||||
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
|
import org.springframework.cache.interceptor.SimpleKey;
|
||||||
|
import org.springframework.cache.interceptor.SimpleKeyGenerator;
|
||||||
|
import org.springframework.cache.jcache.config.JCacheConfigurerSupport;
|
||||||
|
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Stephane Nicoll
|
||||||
|
*/
|
||||||
|
public class JCacheKeyGeneratorTests {
|
||||||
|
|
||||||
|
private TestKeyGenerator keyGenerator;
|
||||||
|
|
||||||
|
private SimpleService simpleService;
|
||||||
|
|
||||||
|
private Cache cache;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setup() {
|
||||||
|
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
|
||||||
|
this.keyGenerator = context.getBean(TestKeyGenerator.class);
|
||||||
|
this.simpleService = context.getBean(SimpleService.class);
|
||||||
|
this.cache = context.getBean(CacheManager.class).getCache("test");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getSimple() {
|
||||||
|
this.keyGenerator.expect(1L);
|
||||||
|
Object first = this.simpleService.get(1L);
|
||||||
|
Object second = this.simpleService.get(1L);
|
||||||
|
assertSame(first, second);
|
||||||
|
|
||||||
|
Object key = new SimpleKey(1L);
|
||||||
|
assertEquals(first, cache.get(key).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getFlattenVararg() {
|
||||||
|
this.keyGenerator.expect(1L, "foo", "bar");
|
||||||
|
Object first = this.simpleService.get(1L, "foo", "bar");
|
||||||
|
Object second = this.simpleService.get(1L, "foo", "bar");
|
||||||
|
assertSame(first, second);
|
||||||
|
|
||||||
|
Object key = new SimpleKey(1L, "foo", "bar");
|
||||||
|
assertEquals(first, cache.get(key).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getFiltered() {
|
||||||
|
this.keyGenerator.expect(1L);
|
||||||
|
Object first = this.simpleService.getFiltered(1L, "foo", "bar");
|
||||||
|
Object second = this.simpleService.getFiltered(1L, "foo", "bar");
|
||||||
|
assertSame(first, second);
|
||||||
|
|
||||||
|
Object key = new SimpleKey(1L);
|
||||||
|
assertEquals(first, cache.get(key).get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@EnableCaching
|
||||||
|
static class Config extends JCacheConfigurerSupport {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Override
|
||||||
|
public CacheManager cacheManager() {
|
||||||
|
return new ConcurrentMapCacheManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Override
|
||||||
|
public KeyGenerator keyGenerator() {
|
||||||
|
return new TestKeyGenerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SimpleService simpleService() {
|
||||||
|
return new SimpleService();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheDefaults(cacheName = "test")
|
||||||
|
public static class SimpleService {
|
||||||
|
private AtomicLong counter = new AtomicLong();
|
||||||
|
|
||||||
|
@CacheResult
|
||||||
|
public Object get(long id) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheResult
|
||||||
|
public Object get(long id, String... items) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
@CacheResult
|
||||||
|
public Object getFiltered(@CacheKey long id, String... items) {
|
||||||
|
return counter.getAndIncrement();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class TestKeyGenerator extends SimpleKeyGenerator {
|
||||||
|
|
||||||
|
private Object[] expectedParams;
|
||||||
|
|
||||||
|
private void expect(Object... params) {
|
||||||
|
this.expectedParams = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object generate(Object target, Method method, Object... params) {
|
||||||
|
assertTrue("Unexpected parameters: expected: "
|
||||||
|
+ Arrays.toString(this.expectedParams) + " but got: " + Arrays.toString(params),
|
||||||
|
Arrays.equals(expectedParams, params));
|
||||||
|
return new SimpleKey(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.springframework.cache.jcache.model;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
import javax.cache.annotation.CacheKey;
|
import javax.cache.annotation.CacheKey;
|
||||||
import javax.cache.annotation.CachePut;
|
import javax.cache.annotation.CachePut;
|
||||||
|
|
@ -6,7 +6,7 @@ import javax.cache.annotation.CacheKeyGenerator;
|
||||||
import javax.cache.annotation.CacheKeyInvocationContext;
|
import javax.cache.annotation.CacheKeyInvocationContext;
|
||||||
import javax.cache.annotation.GeneratedCacheKey;
|
import javax.cache.annotation.GeneratedCacheKey;
|
||||||
|
|
||||||
import org.springframework.cache.jcache.interceptor.SimpleGeneratedCacheKey;
|
import org.springframework.cache.interceptor.SimpleKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple test key generator that only takes the first key arguments into
|
* A simple test key generator that only takes the first key arguments into
|
||||||
|
|
@ -22,4 +22,13 @@ public class TestableCacheKeyGenerator implements CacheKeyGenerator {
|
||||||
return new SimpleGeneratedCacheKey(context.getKeyParameters()[0]);
|
return new SimpleGeneratedCacheKey(context.getKeyParameters()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class SimpleGeneratedCacheKey extends SimpleKey implements GeneratedCacheKey {
|
||||||
|
|
||||||
|
public SimpleGeneratedCacheKey(Object... elements) {
|
||||||
|
super(elements);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,16 +33,18 @@ import org.springframework.util.Assert;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public abstract class BaseCacheResolver implements CacheResolver, InitializingBean {
|
public abstract class AbstractCacheResolver implements CacheResolver, InitializingBean {
|
||||||
|
|
||||||
private CacheManager cacheManager;
|
private CacheManager cacheManager;
|
||||||
|
|
||||||
protected BaseCacheResolver(CacheManager cacheManager) {
|
|
||||||
|
protected AbstractCacheResolver() {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected AbstractCacheResolver(CacheManager cacheManager) {
|
||||||
this.cacheManager = cacheManager;
|
this.cacheManager = cacheManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected BaseCacheResolver() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the {@link CacheManager} that this instance should use.
|
* Set the {@link CacheManager} that this instance should use.
|
||||||
|
|
@ -55,14 +57,15 @@ public abstract class BaseCacheResolver implements CacheResolver, InitializingBe
|
||||||
* Return the {@link CacheManager} that this instance use.
|
* Return the {@link CacheManager} that this instance use.
|
||||||
*/
|
*/
|
||||||
public CacheManager getCacheManager() {
|
public CacheManager getCacheManager() {
|
||||||
return cacheManager;
|
return this.cacheManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
Assert.notNull(cacheManager, "CacheManager must not be null");
|
Assert.notNull(this.cacheManager, "CacheManager must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
|
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
|
||||||
Collection<String> cacheNames = getCacheNames(context);
|
Collection<String> cacheNames = getCacheNames(context);
|
||||||
|
|
@ -72,8 +75,11 @@ public abstract class BaseCacheResolver implements CacheResolver, InitializingBe
|
||||||
else {
|
else {
|
||||||
Collection<Cache> result = new ArrayList<Cache>();
|
Collection<Cache> result = new ArrayList<Cache>();
|
||||||
for (String cacheName : cacheNames) {
|
for (String cacheName : cacheNames) {
|
||||||
Cache cache = cacheManager.getCache(cacheName);
|
Cache cache = this.cacheManager.getCache(cacheName);
|
||||||
Assert.notNull(cache, "Cannot find cache named '" + cacheName + "' for " + context.getOperation());
|
if (cache == null) {
|
||||||
|
throw new IllegalArgumentException("Cannot find cache named '" +
|
||||||
|
cacheName + "' for " + context.getOperation());
|
||||||
|
}
|
||||||
result.add(cache);
|
result.add(cache);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -84,7 +90,6 @@ public abstract class BaseCacheResolver implements CacheResolver, InitializingBe
|
||||||
* Provide the name of the cache(s) to resolve against the current cache manager.
|
* Provide the name of the cache(s) to resolve against the current cache manager.
|
||||||
* <p>It is acceptable to return {@code null} to indicate that no cache could
|
* <p>It is acceptable to return {@code null} to indicate that no cache could
|
||||||
* be resolved for this invocation.
|
* be resolved for this invocation.
|
||||||
*
|
|
||||||
* @param context the context of the particular invocation
|
* @param context the context of the particular invocation
|
||||||
* @return the cache name(s) to resolve or {@code null} if no cache should be resolved
|
* @return the cache name(s) to resolve or {@code null} if no cache should be resolved
|
||||||
*/
|
*/
|
||||||
|
|
@ -24,7 +24,7 @@ import java.util.Set;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public interface BasicCacheOperation {
|
public interface BasicOperation {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the cache name(s) associated to the operation.
|
* Return the cache name(s) associated to the operation.
|
||||||
|
|
@ -29,7 +29,7 @@ import org.springframework.util.Assert;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public abstract class CacheOperation implements BasicCacheOperation {
|
public abstract class CacheOperation implements BasicOperation {
|
||||||
|
|
||||||
private Set<String> cacheNames = Collections.emptySet();
|
private Set<String> cacheNames = Collections.emptySet();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import java.lang.reflect.Method;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public interface CacheOperationInvocationContext<O extends BasicCacheOperation> {
|
public interface CacheOperationInvocationContext<O extends BasicOperation> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the cache operation
|
* Return the cache operation
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import org.springframework.cache.CacheManager;
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
*/
|
*/
|
||||||
public class NamedCacheResolver extends BaseCacheResolver {
|
public class NamedCacheResolver extends AbstractCacheResolver {
|
||||||
|
|
||||||
private Collection<String> cacheNames;
|
private Collection<String> cacheNames;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,13 @@ import org.springframework.cache.CacheManager;
|
||||||
/**
|
/**
|
||||||
* A simple {@link CacheResolver} that resolves the {@link Cache} instance(s)
|
* A simple {@link CacheResolver} that resolves the {@link Cache} instance(s)
|
||||||
* based on a configurable {@link CacheManager} and the name of the
|
* based on a configurable {@link CacheManager} and the name of the
|
||||||
* cache(s) as provided by {@link BasicCacheOperation#getCacheNames() getCacheNames()}
|
* cache(s) as provided by {@link BasicOperation#getCacheNames() getCacheNames()}
|
||||||
*
|
*
|
||||||
* @author Stephane Nicoll
|
* @author Stephane Nicoll
|
||||||
* @since 4.1
|
* @since 4.1
|
||||||
* @see BasicCacheOperation#getCacheNames()
|
* @see BasicOperation#getCacheNames()
|
||||||
*/
|
*/
|
||||||
public class SimpleCacheResolver extends BaseCacheResolver {
|
public class SimpleCacheResolver extends AbstractCacheResolver {
|
||||||
|
|
||||||
public SimpleCacheResolver() {
|
public SimpleCacheResolver() {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,13 @@ public class SimpleKeyGenerator implements KeyGenerator {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object generate(Object target, Method method, Object... params) {
|
public Object generate(Object target, Method method, Object... params) {
|
||||||
|
return generateKey(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a key based on the specified parameters.
|
||||||
|
*/
|
||||||
|
public static Object generateKey(Object... params) {
|
||||||
if (params.length == 0) {
|
if (params.length == 0) {
|
||||||
return SimpleKey.EMPTY;
|
return SimpleKey.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,7 @@ public class CacheResolverCustomisationTests {
|
||||||
* runtime (i.e. based on method invocation parameters).
|
* runtime (i.e. based on method invocation parameters).
|
||||||
* <p>Expects the second argument to hold the name of the cache to use
|
* <p>Expects the second argument to hold the name of the cache to use
|
||||||
*/
|
*/
|
||||||
private static class RuntimeCacheResolver extends BaseCacheResolver {
|
private static class RuntimeCacheResolver extends AbstractCacheResolver {
|
||||||
|
|
||||||
private RuntimeCacheResolver(CacheManager cacheManager) {
|
private RuntimeCacheResolver(CacheManager cacheManager) {
|
||||||
super(cacheManager);
|
super(cacheManager);
|
||||||
|
|
@ -263,7 +263,7 @@ public class CacheResolverCustomisationTests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class NullCacheResolver extends BaseCacheResolver {
|
private static class NullCacheResolver extends AbstractCacheResolver {
|
||||||
|
|
||||||
private NullCacheResolver(CacheManager cacheManager) {
|
private NullCacheResolver(CacheManager cacheManager) {
|
||||||
super(cacheManager);
|
super(cacheManager);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue