Browse Source
- eliminate unneeded methods + introduced value wrapper (name still to be decided) to avoid cache race conditions + improved name consistency git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4315 50f2f4bb-b051-0410-bef5-90022cba6387pull/1/merge
25 changed files with 121 additions and 1371 deletions
@ -1,125 +0,0 @@
@@ -1,125 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.annotation; |
||||
|
||||
import java.io.Serializable; |
||||
import java.lang.reflect.AnnotatedElement; |
||||
import java.lang.reflect.Method; |
||||
import java.util.Collections; |
||||
import java.util.LinkedHashSet; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.cache.interceptor.AbstractFallbackCacheDefinitionSource; |
||||
import org.springframework.cache.interceptor.CacheDefinition; |
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* |
||||
* Implementation of the |
||||
* {@link org.springframework.cache.interceptor.CacheDefinitionSource} |
||||
* interface for working with caching metadata in JDK 1.5+ annotation format. |
||||
* |
||||
* <p>This class reads Spring's JDK 1.5+ {@link Cacheable} and {@link CacheEvict} |
||||
* annotations and |
||||
* exposes corresponding caching operation definition to Spring's cache infrastructure. |
||||
* This class may also serve as base class for a custom CacheDefinitionSource. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
@SuppressWarnings("serial") |
||||
public class AnnotationCacheDefinitionSource extends AbstractFallbackCacheDefinitionSource implements |
||||
Serializable { |
||||
|
||||
private final boolean publicMethodsOnly; |
||||
|
||||
private final Set<CacheAnnotationParser> annotationParsers; |
||||
|
||||
/** |
||||
* Create a default AnnotationCacheOperationDefinitionSource, supporting |
||||
* public methods that carry the <code>Cacheable</code> and <code>CacheInvalidate</code> |
||||
* annotations. |
||||
*/ |
||||
public AnnotationCacheDefinitionSource() { |
||||
this(true); |
||||
} |
||||
|
||||
/** |
||||
* Create a custom AnnotationCacheOperationDefinitionSource, supporting |
||||
* public methods that carry the <code>Cacheable</code> and |
||||
* <code>CacheInvalidate</code> annotations. |
||||
* |
||||
* @param publicMethodsOnly whether to support only annotated public methods |
||||
* typically for use with proxy-based AOP), or protected/private methods as well |
||||
* (typically used with AspectJ class weaving) |
||||
*/ |
||||
public AnnotationCacheDefinitionSource(boolean publicMethodsOnly) { |
||||
this.publicMethodsOnly = publicMethodsOnly; |
||||
this.annotationParsers = new LinkedHashSet<CacheAnnotationParser>(1); |
||||
this.annotationParsers.add(new SpringCachingAnnotationParser()); |
||||
} |
||||
|
||||
/** |
||||
* Create a custom AnnotationCacheOperationDefinitionSource. |
||||
* @param annotationParsers the CacheAnnotationParser to use |
||||
*/ |
||||
public AnnotationCacheDefinitionSource(CacheAnnotationParser... annotationParsers) { |
||||
this.publicMethodsOnly = true; |
||||
Assert.notEmpty(annotationParsers, "At least one CacheAnnotationParser needs to be specified"); |
||||
Set<CacheAnnotationParser> parsers = new LinkedHashSet<CacheAnnotationParser>(annotationParsers.length); |
||||
Collections.addAll(parsers, annotationParsers); |
||||
this.annotationParsers = parsers; |
||||
} |
||||
|
||||
@Override |
||||
protected CacheDefinition findCacheDefinition(Class<?> clazz) { |
||||
return determineCacheDefinition(clazz); |
||||
} |
||||
|
||||
@Override |
||||
protected CacheDefinition findCacheOperation(Method method) { |
||||
return determineCacheDefinition(method); |
||||
} |
||||
|
||||
/** |
||||
* Determine the cache operation definition for the given method or class. |
||||
* <p>This implementation delegates to configured |
||||
* {@link CacheAnnotationParser CacheAnnotationParsers} |
||||
* for parsing known annotations into Spring's metadata attribute class. |
||||
* Returns <code>null</code> if it's not cacheable. |
||||
* <p>Can be overridden to support custom annotations that carry caching metadata. |
||||
* @param ae the annotated method or class
|
||||
* @return CacheOperationDefinition the configured caching operation, |
||||
* or <code>null</code> if none was found |
||||
*/ |
||||
protected CacheDefinition determineCacheDefinition(AnnotatedElement ae) { |
||||
for (CacheAnnotationParser annotationParser : this.annotationParsers) { |
||||
CacheDefinition attr = annotationParser.parseCacheAnnotation(ae); |
||||
if (attr != null) { |
||||
return attr; |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* By default, only public methods can be made cacheable. |
||||
*/ |
||||
@Override |
||||
protected boolean allowPublicMethodsOnly() { |
||||
return this.publicMethodsOnly; |
||||
} |
||||
} |
||||
@ -1,128 +0,0 @@
@@ -1,128 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.LinkedHashSet; |
||||
import java.util.Set; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* Base class implementing {@link CacheDefinition}. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
abstract class AbstractCacheDefinition implements CacheDefinition { |
||||
|
||||
private Set<String> cacheNames = Collections.emptySet(); |
||||
private String condition = ""; |
||||
private String key = ""; |
||||
private String name = ""; |
||||
|
||||
|
||||
public Set<String> getCacheNames() { |
||||
return cacheNames; |
||||
} |
||||
|
||||
public String getCondition() { |
||||
return condition; |
||||
} |
||||
|
||||
public String getKey() { |
||||
return key; |
||||
} |
||||
|
||||
public String getName() { |
||||
return name; |
||||
} |
||||
|
||||
public void setCacheName(String cacheName) { |
||||
Assert.hasText(cacheName); |
||||
this.cacheNames = Collections.singleton(cacheName); |
||||
} |
||||
|
||||
public void setCacheNames(String[] cacheNames) { |
||||
Assert.notEmpty(cacheNames); |
||||
this.cacheNames = new LinkedHashSet<String>(cacheNames.length); |
||||
for (String string : cacheNames) { |
||||
this.cacheNames.add(string); |
||||
} |
||||
} |
||||
|
||||
public void setCondition(String condition) { |
||||
Assert.notNull(condition); |
||||
this.condition = condition; |
||||
} |
||||
|
||||
public void setKey(String key) { |
||||
Assert.notNull(key); |
||||
this.key = key; |
||||
} |
||||
|
||||
public void setName(String name) { |
||||
Assert.hasText(name); |
||||
this.name = name; |
||||
} |
||||
|
||||
/** |
||||
* This implementation compares the <code>toString()</code> results. |
||||
* @see #toString() |
||||
*/ |
||||
@Override |
||||
public boolean equals(Object other) { |
||||
return (other instanceof CacheDefinition && toString().equals(other.toString())); |
||||
} |
||||
|
||||
/** |
||||
* This implementation returns <code>toString()</code>'s hash code. |
||||
* @see #toString() |
||||
*/ |
||||
@Override |
||||
public int hashCode() { |
||||
return toString().hashCode(); |
||||
} |
||||
|
||||
/** |
||||
* Return an identifying description for this cache operation definition. |
||||
* <p>Has to be overridden in subclasses for correct <code>equals</code> |
||||
* and <code>hashCode</code> behavior. Alternatively, {@link #equals} |
||||
* and {@link #hashCode} can be overridden themselves. |
||||
*/ |
||||
@Override |
||||
public String toString() { |
||||
return getDefinitionDescription().toString(); |
||||
} |
||||
|
||||
/** |
||||
* Return an identifying description for this caching definition. |
||||
* <p>Available to subclasses, for inclusion in their <code>toString()</code> result. |
||||
*/ |
||||
protected StringBuilder getDefinitionDescription() { |
||||
StringBuilder result = new StringBuilder(); |
||||
result.append("CacheDefinition["); |
||||
result.append(name); |
||||
result.append("] caches="); |
||||
result.append(cacheNames); |
||||
result.append(" | condition='"); |
||||
result.append(condition); |
||||
result.append("' | key='"); |
||||
result.append(key); |
||||
result.append("'"); |
||||
return result; |
||||
} |
||||
} |
||||
@ -1,218 +0,0 @@
@@ -1,218 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
import java.lang.reflect.Method; |
||||
import java.lang.reflect.Modifier; |
||||
import java.util.Map; |
||||
import java.util.concurrent.ConcurrentHashMap; |
||||
|
||||
import org.apache.commons.logging.Log; |
||||
import org.apache.commons.logging.LogFactory; |
||||
import org.springframework.core.BridgeMethodResolver; |
||||
import org.springframework.util.ClassUtils; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* Abstract implementation of {@link CacheDefinition} that caches |
||||
* attributes for methods and implements a fallback policy: 1. specific target |
||||
* method; 2. target class; 3. declaring method; 4. declaring class/interface. |
||||
* |
||||
* <p>Defaults to using the target class's caching attribute if none is |
||||
* associated with the target method. Any caching attribute associated with |
||||
* the target method completely overrides a class caching attribute. |
||||
* If none found on the target class, the interface that the invoked method |
||||
* has been called through (in case of a JDK proxy) will be checked. |
||||
* |
||||
* <p>This implementation caches attributes by method after they are first used. |
||||
* If it is ever desirable to allow dynamic changing of cacheable attributes |
||||
* (which is very unlikely), caching could be made configurable. |
||||
|
||||
* @author Costin Leau |
||||
* @see org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource |
||||
*/ |
||||
public abstract class AbstractFallbackCacheDefinitionSource implements CacheDefinitionSource { |
||||
|
||||
/** |
||||
* Canonical value held in cache to indicate no caching attribute was |
||||
* found for this method, and we don't need to look again. |
||||
*/ |
||||
private final static CacheDefinition NULL_CACHING_ATTRIBUTE = new DefaultCacheUpdateDefinition(); |
||||
|
||||
/** |
||||
* Logger available to subclasses. |
||||
* <p>As this base class is not marked Serializable, the logger will be recreated |
||||
* after serialization - provided that the concrete subclass is Serializable. |
||||
*/ |
||||
protected final Log logger = LogFactory.getLog(getClass()); |
||||
|
||||
/** |
||||
* Cache of CacheOperationDefinitions, keyed by DefaultCacheKey (Method + target Class). |
||||
* <p>As this base class is not marked Serializable, the cache will be recreated |
||||
* after serialization - provided that the concrete subclass is Serializable. |
||||
*/ |
||||
final Map<Object, CacheDefinition> attributeCache = new ConcurrentHashMap<Object, CacheDefinition>(); |
||||
|
||||
/** |
||||
* Determine the caching attribute for this method invocation. |
||||
* <p>Defaults to the class's caching attribute if no method attribute is found. |
||||
* @param method the method for the current invocation (never <code>null</code>) |
||||
* @param targetClass the target class for this invocation (may be <code>null</code>) |
||||
* @return {@link CacheDefinition} for this method, or <code>null</code> if the method |
||||
* is not cacheable |
||||
*/ |
||||
public CacheDefinition getCacheDefinition(Method method, Class<?> targetClass) { |
||||
// First, see if we have a cached value.
|
||||
Object cacheKey = getCacheKey(method, targetClass); |
||||
CacheDefinition cached = this.attributeCache.get(cacheKey); |
||||
if (cached != null) { |
||||
if (cached == NULL_CACHING_ATTRIBUTE) { |
||||
return null; |
||||
} |
||||
// Value will either be canonical value indicating there is no caching attribute,
|
||||
// or an actual caching attribute.
|
||||
return cached; |
||||
} |
||||
else { |
||||
// We need to work it out.
|
||||
CacheDefinition cacheDef = computeCacheOperationDefinition(method, targetClass); |
||||
// Put it in the cache.
|
||||
if (cacheDef == null) { |
||||
this.attributeCache.put(cacheKey, NULL_CACHING_ATTRIBUTE); |
||||
} |
||||
else { |
||||
if (logger.isDebugEnabled()) { |
||||
logger.debug("Adding cacheable method '" + method.getName() + "' with attribute: " + cacheDef); |
||||
} |
||||
this.attributeCache.put(cacheKey, cacheDef); |
||||
} |
||||
return cacheDef; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Determine a cache key for the given method and target class. |
||||
* <p>Must not produce same key for overloaded methods. |
||||
* Must produce same key for different instances of the same method. |
||||
* @param method the method (never <code>null</code>) |
||||
* @param targetClass the target class (may be <code>null</code>) |
||||
* @return the cache key (never <code>null</code>) |
||||
*/ |
||||
protected Object getCacheKey(Method method, Class<?> targetClass) { |
||||
return new DefaultCacheKey(method, targetClass); |
||||
} |
||||
|
||||
/** |
||||
* Same signature as {@link #getTransactionAttribute}, but doesn't cache the result. |
||||
* {@link #getTransactionAttribute} is effectively a caching decorator for this method. |
||||
* @see #getTransactionAttribute |
||||
*/ |
||||
private CacheDefinition computeCacheOperationDefinition(Method method, Class<?> targetClass) { |
||||
// Don't allow no-public methods as required.
|
||||
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) { |
||||
return null; |
||||
} |
||||
|
||||
// The method may be on an interface, but we need attributes from the target class.
|
||||
// If the target class is null, the method will be unchanged.
|
||||
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass); |
||||
// If we are dealing with method with generic parameters, find the original method.
|
||||
specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); |
||||
|
||||
// First try is the method in the target class.
|
||||
CacheDefinition opDef = findCacheOperation(specificMethod); |
||||
if (opDef != null) { |
||||
return opDef; |
||||
} |
||||
|
||||
// Second try is the caching operation on the target class.
|
||||
opDef = findCacheDefinition(specificMethod.getDeclaringClass()); |
||||
if (opDef != null) { |
||||
return opDef; |
||||
} |
||||
|
||||
if (specificMethod != method) { |
||||
// Fall back is to look at the original method.
|
||||
opDef = findCacheOperation(method); |
||||
if (opDef != null) { |
||||
return opDef; |
||||
} |
||||
// Last fall back is the class of the original method.
|
||||
return findCacheDefinition(method.getDeclaringClass()); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Subclasses need to implement this to return the caching attribute |
||||
* for the given method, if any. |
||||
* @param method the method to retrieve the attribute for |
||||
* @return all caching attribute associated with this method |
||||
* (or <code>null</code> if none) |
||||
*/ |
||||
protected abstract CacheDefinition findCacheOperation(Method method); |
||||
|
||||
/** |
||||
* Subclasses need to implement this to return the caching attribute |
||||
* for the given class, if any. |
||||
* @param clazz the class to retrieve the attribute for |
||||
* @return all caching attribute associated with this class
|
||||
* (or <code>null</code> if none) |
||||
*/ |
||||
protected abstract CacheDefinition findCacheDefinition(Class<?> clazz); |
||||
|
||||
/** |
||||
* Should only public methods be allowed to have caching semantics? |
||||
* <p>The default implementation returns <code>false</code>. |
||||
*/ |
||||
protected boolean allowPublicMethodsOnly() { |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Default cache key for the CacheOperationDefinition cache. |
||||
*/ |
||||
private static class DefaultCacheKey { |
||||
|
||||
private final Method method; |
||||
|
||||
private final Class<?> targetClass; |
||||
|
||||
public DefaultCacheKey(Method method, Class<?> targetClass) { |
||||
this.method = method; |
||||
this.targetClass = targetClass; |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object other) { |
||||
if (this == other) { |
||||
return true; |
||||
} |
||||
if (!(other instanceof DefaultCacheKey)) { |
||||
return false; |
||||
} |
||||
DefaultCacheKey otherKey = (DefaultCacheKey) other; |
||||
return (this.method.equals(otherKey.method) && ObjectUtils.nullSafeEquals(this.targetClass, |
||||
otherKey.targetClass)); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return this.method.hashCode() * 29 + (this.targetClass != null ? this.targetClass.hashCode() : 0); |
||||
} |
||||
} |
||||
} |
||||
@ -1,62 +0,0 @@
@@ -1,62 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
import org.springframework.aop.ClassFilter; |
||||
import org.springframework.aop.Pointcut; |
||||
import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor; |
||||
|
||||
/** |
||||
* Advisor driven by a {@link CacheDefinitionSource}, used to include a |
||||
* transaction advice bean for methods that are transactional. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
@SuppressWarnings("serial") |
||||
public class BeanFactoryCacheDefinitionSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor { |
||||
|
||||
private CacheDefinitionSource cacheDefinitionSource; |
||||
|
||||
private final CacheDefinitionSourcePointcut pointcut = new CacheDefinitionSourcePointcut() { |
||||
@Override |
||||
protected CacheDefinitionSource getCacheDefinitionSource() { |
||||
return cacheDefinitionSource; |
||||
} |
||||
}; |
||||
|
||||
/** |
||||
* Set the cache operation attribute source which is used to find cache |
||||
* attributes. This should usually be identical to the source reference |
||||
* set on the cache interceptor itself. |
||||
* @see CacheInterceptor#setCacheAttributeSource |
||||
*/ |
||||
public void setCacheDefinitionSource(CacheDefinitionSource cacheDefinitionSource) { |
||||
this.cacheDefinitionSource = cacheDefinitionSource; |
||||
} |
||||
|
||||
/** |
||||
* Set the {@link ClassFilter} to use for this pointcut. |
||||
* Default is {@link ClassFilter#TRUE}. |
||||
*/ |
||||
public void setClassFilter(ClassFilter classFilter) { |
||||
this.pointcut.setClassFilter(classFilter); |
||||
} |
||||
|
||||
public Pointcut getPointcut() { |
||||
return this.pointcut; |
||||
} |
||||
} |
||||
@ -1,58 +0,0 @@
@@ -1,58 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
import java.util.Set; |
||||
|
||||
/** |
||||
* Interface describing Spring-compliant caching operation. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
public interface CacheDefinition { |
||||
|
||||
/** |
||||
* Returns the name of this operation. Can be <tt>null</tt>. |
||||
* In case of Spring's declarative caching, the exposed name will be: |
||||
* <tt>fully qualified class name.method name</tt>. |
||||
* |
||||
* @return the operation name |
||||
*/ |
||||
String getName(); |
||||
|
||||
/** |
||||
* Returns the names of the cache against which this operation is performed. |
||||
* |
||||
* @return names of the cache on which the operation is performed. |
||||
*/ |
||||
Set<String> getCacheNames(); |
||||
|
||||
/** |
||||
* Returns the SpEL expression conditioning the operation. |
||||
* |
||||
* @return operation condition (as SpEL expression). |
||||
*/ |
||||
String getCondition(); |
||||
|
||||
/** |
||||
* Returns the SpEL expression identifying the cache key. |
||||
* |
||||
* @return |
||||
*/ |
||||
String getKey(); |
||||
|
||||
} |
||||
@ -1,41 +0,0 @@
@@ -1,41 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
import java.lang.reflect.Method; |
||||
|
||||
|
||||
/** |
||||
* Interface used by CacheInterceptor. Implementations know |
||||
* how to source cache operation attributes, whether from configuration, |
||||
* metadata attributes at source level, or anywhere else. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
public interface CacheDefinitionSource { |
||||
|
||||
/** |
||||
* Return the cache operation definition for this method. |
||||
* Return null if the method is not cacheable. |
||||
* @param method method |
||||
* @param targetClass target class. May be <code>null</code>, in which |
||||
* case the declaring class of the method must be used. |
||||
* @return {@link CacheDefinition} the matching cache operation definition, |
||||
* or <code>null</code> if none found |
||||
*/ |
||||
CacheDefinition getCacheDefinition(Method method, Class<?> targetClass); |
||||
} |
||||
@ -1,68 +0,0 @@
@@ -1,68 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
import java.io.Serializable; |
||||
import java.lang.reflect.Method; |
||||
|
||||
import org.springframework.aop.support.StaticMethodMatcherPointcut; |
||||
import org.springframework.util.ObjectUtils; |
||||
|
||||
/** |
||||
* Inner class that implements a Pointcut that matches if the underlying |
||||
* {@link CacheDefinitionSource} has an attribute for a given method. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
@SuppressWarnings("serial") |
||||
abstract class CacheDefinitionSourcePointcut extends StaticMethodMatcherPointcut implements Serializable { |
||||
|
||||
public boolean matches(Method method, Class<?> targetClass) { |
||||
CacheDefinitionSource cas = getCacheDefinitionSource(); |
||||
return (cas == null || cas.getCacheDefinition(method, targetClass) != null); |
||||
} |
||||
|
||||
@Override |
||||
public boolean equals(Object other) { |
||||
if (this == other) { |
||||
return true; |
||||
} |
||||
if (!(other instanceof CacheDefinitionSourcePointcut)) { |
||||
return false; |
||||
} |
||||
CacheDefinitionSourcePointcut otherPc = (CacheDefinitionSourcePointcut) other; |
||||
return ObjectUtils.nullSafeEquals(getCacheDefinitionSource(), |
||||
otherPc.getCacheDefinitionSource()); |
||||
} |
||||
|
||||
@Override |
||||
public int hashCode() { |
||||
return CacheDefinitionSourcePointcut.class.hashCode(); |
||||
} |
||||
|
||||
@Override |
||||
public String toString() { |
||||
return getClass().getName() + ": " + getCacheDefinitionSource(); |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Obtain the underlying CacheOperationDefinitionSource (may be <code>null</code>). |
||||
* To be implemented by subclasses. |
||||
*/ |
||||
protected abstract CacheDefinitionSource getCacheDefinitionSource(); |
||||
} |
||||
@ -1,33 +0,0 @@
@@ -1,33 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
|
||||
/** |
||||
* Interface describing a Spring cache invalidation. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
public interface CacheInvalidateDefinition extends CacheDefinition { |
||||
|
||||
/** |
||||
* Returns whether the operation affects the entire cache or not. |
||||
* |
||||
* @return whether the operation is cache wide or not. |
||||
*/ |
||||
boolean isCacheWide(); |
||||
} |
||||
@ -1,32 +0,0 @@
@@ -1,32 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
/** |
||||
* Interface describing a Spring cache update. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
public interface CacheUpdateDefinition extends CacheDefinition { |
||||
|
||||
/** |
||||
* Returns the SpEL expression identifying the cache key. |
||||
* |
||||
* @return |
||||
*/ |
||||
String getKey(); |
||||
} |
||||
@ -1,63 +0,0 @@
@@ -1,63 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
import java.io.Serializable; |
||||
import java.lang.reflect.Method; |
||||
|
||||
import org.springframework.util.Assert; |
||||
|
||||
/** |
||||
* Composite {@link CacheDefinitionSource} implementation that iterates |
||||
* over a given array of {@link CacheDefinitionSource} instances. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
@SuppressWarnings("serial") |
||||
public class CompositeCacheDefinitionSource implements CacheDefinitionSource, Serializable { |
||||
|
||||
private final CacheDefinitionSource[] cacheDefinitionSources; |
||||
|
||||
/** |
||||
* Create a new CompositeCachingDefinitionSource for the given sources. |
||||
* @param cacheDefinitionSourcess the CacheDefinitionSource instances to combine |
||||
*/ |
||||
public CompositeCacheDefinitionSource(CacheDefinitionSource[] cacheDefinitionSources) { |
||||
Assert.notNull(cacheDefinitionSources, "cacheDefinitionSource array must not be null"); |
||||
this.cacheDefinitionSources = cacheDefinitionSources; |
||||
} |
||||
|
||||
/** |
||||
* Return the CacheDefinitionSource instances that this |
||||
* CompositeCachingDefinitionSource combines. |
||||
*/ |
||||
public final CacheDefinitionSource[] getCacheDefinitionSources() { |
||||
return this.cacheDefinitionSources; |
||||
} |
||||
|
||||
|
||||
public CacheDefinition getCacheDefinition(Method method, Class<?> targetClass) { |
||||
for (CacheDefinitionSource source : cacheDefinitionSources) { |
||||
CacheDefinition definition = source.getCacheDefinition(method, targetClass); |
||||
if (definition != null) { |
||||
return definition; |
||||
} |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
} |
||||
@ -1,44 +0,0 @@
@@ -1,44 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
/** |
||||
* Default implementation of the {@link CacheInvalidateDefinition} interface. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
public class DefaultCacheInvalidateDefinition extends AbstractCacheDefinition implements |
||||
CacheInvalidateDefinition { |
||||
|
||||
private boolean cacheWide = false; |
||||
|
||||
public boolean isCacheWide() { |
||||
return cacheWide; |
||||
} |
||||
|
||||
public void setCacheWide(boolean cacheWide) { |
||||
this.cacheWide = cacheWide; |
||||
} |
||||
|
||||
@Override |
||||
protected StringBuilder getDefinitionDescription() { |
||||
StringBuilder sb = super.getDefinitionDescription(); |
||||
sb.append(","); |
||||
sb.append(cacheWide); |
||||
return sb; |
||||
} |
||||
} |
||||
@ -1,27 +0,0 @@
@@ -1,27 +0,0 @@
|
||||
/* |
||||
* Copyright 2010-2011 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.interceptor; |
||||
|
||||
/** |
||||
* Default implementation of the {@link CacheUpdateDefinition} interface. |
||||
* |
||||
* @author Costin Leau |
||||
*/ |
||||
public class DefaultCacheUpdateDefinition extends AbstractCacheDefinition implements CacheUpdateDefinition { |
||||
|
||||
|
||||
} |
||||
Loading…
Reference in new issue