|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2002-2014 the original author or authors. |
|
|
|
* Copyright 2002-2015 the original author or authors. |
|
|
|
* |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -29,19 +29,18 @@ import org.springframework.core.BridgeMethodResolver; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Abstract implementation of {@link JCacheOperationSource} that caches |
|
|
|
* Abstract implementation of {@link JCacheOperationSource} that caches attributes |
|
|
|
* attributes for methods and implements a fallback policy: 1. specific |
|
|
|
* for methods and implements a fallback policy: 1. specific target method; |
|
|
|
* target method; 2. declaring method. |
|
|
|
* 2. declaring method. |
|
|
|
* |
|
|
|
* |
|
|
|
* <p>This implementation caches attributes by method after they are |
|
|
|
* <p>This implementation caches attributes by method after they are first used. |
|
|
|
* first used. |
|
|
|
|
|
|
|
* |
|
|
|
* |
|
|
|
* @author Stephane Nicoll |
|
|
|
* @author Stephane Nicoll |
|
|
|
|
|
|
|
* @author Juergen Hoeller |
|
|
|
* @since 4.1 |
|
|
|
* @since 4.1 |
|
|
|
* @see org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource |
|
|
|
* @see org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public abstract class AbstractFallbackJCacheOperationSource |
|
|
|
public abstract class AbstractFallbackJCacheOperationSource implements JCacheOperationSource { |
|
|
|
implements JCacheOperationSource { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Canonical value held in cache to indicate no caching attribute was |
|
|
|
* Canonical value held in cache to indicate no caching attribute was |
|
|
|
@ -49,34 +48,31 @@ public abstract class AbstractFallbackJCacheOperationSource |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
private final static Object NULL_CACHING_ATTRIBUTE = new Object(); |
|
|
|
private final static Object NULL_CACHING_ATTRIBUTE = new Object(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected final Log logger = LogFactory.getLog(getClass()); |
|
|
|
protected final Log logger = LogFactory.getLog(getClass()); |
|
|
|
|
|
|
|
|
|
|
|
private final Map<Object, Object> cache = |
|
|
|
private final Map<Object, Object> cache = new ConcurrentHashMap<Object, Object>(1024); |
|
|
|
new ConcurrentHashMap<Object, Object>(1024); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public JCacheOperation<?> getCacheOperation(Method method, Class<?> targetClass) { |
|
|
|
public JCacheOperation<?> getCacheOperation(Method method, Class<?> targetClass) { |
|
|
|
// First, see if we have a cached value.
|
|
|
|
|
|
|
|
Object cacheKey = new MethodCacheKey(method, targetClass); |
|
|
|
Object cacheKey = new MethodCacheKey(method, targetClass); |
|
|
|
Object cached = this.cache.get(cacheKey); |
|
|
|
Object cached = this.cache.get(cacheKey); |
|
|
|
|
|
|
|
|
|
|
|
if (cached != null) { |
|
|
|
if (cached != null) { |
|
|
|
if (cached == NULL_CACHING_ATTRIBUTE) { |
|
|
|
return (cached != NULL_CACHING_ATTRIBUTE ? (JCacheOperation<?>) cached : null); |
|
|
|
return null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return (JCacheOperation<?>) cached; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
else { |
|
|
|
JCacheOperation<?> operation = computeCacheOperation(method, targetClass); |
|
|
|
JCacheOperation<?> operation = computeCacheOperation(method, targetClass); |
|
|
|
if (operation == null) { |
|
|
|
if (operation != null) { |
|
|
|
this.cache.put(cacheKey, NULL_CACHING_ATTRIBUTE); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
if (logger.isDebugEnabled()) { |
|
|
|
if (logger.isDebugEnabled()) { |
|
|
|
logger.debug("Adding cacheable method '" + method.getName() |
|
|
|
logger.debug("Adding cacheable method '" + method.getName() + "' with operation: " + operation); |
|
|
|
+ "' with operation: " + operation); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
this.cache.put(cacheKey, operation); |
|
|
|
this.cache.put(cacheKey, operation); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
this.cache.put(cacheKey, NULL_CACHING_ATTRIBUTE); |
|
|
|
|
|
|
|
} |
|
|
|
return operation; |
|
|
|
return operation; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -108,6 +104,7 @@ public abstract class AbstractFallbackJCacheOperationSource |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Subclasses need to implement this to return the caching operation |
|
|
|
* Subclasses need to implement this to return the caching operation |
|
|
|
* for the given method, if any. |
|
|
|
* for the given method, if any. |
|
|
|
|