Browse Source

general revision of cache package; added ConcurrentMapCacheManager

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4760 50f2f4bb-b051-0410-bef5-90022cba6387
pull/2/head
Juergen Hoeller 15 years ago
parent
commit
6ec0405287
  1. 70
      org.springframework.context/src/main/java/org/springframework/cache/Cache.java
  2. 21
      org.springframework.context/src/main/java/org/springframework/cache/CacheManager.java
  3. 25
      org.springframework.context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java
  4. 4
      org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheAnnotationParser.java
  5. 19
      org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheEvict.java
  6. 12
      org.springframework.context/src/main/java/org/springframework/cache/annotation/Cacheable.java
  7. 68
      org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java
  8. 84
      org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCachingAnnotationParser.java
  9. 125
      org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java
  10. 77
      org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheFactoryBean.java
  11. 101
      org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java
  12. 17
      org.springframework.context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java
  13. 4
      org.springframework.context/src/main/java/org/springframework/cache/config/CacheNamespaceHandler.java
  14. 36
      org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java
  15. 54
      org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java
  16. 14
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java
  17. 15
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java
  18. 173
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java
  19. 17
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java
  20. 101
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheExpressionRootObject.java
  21. 21
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheInterceptor.java
  22. 10
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java
  23. 17
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSource.java
  24. 10
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java
  25. 4
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheProxyFactoryBean.java
  26. 7
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheUpdateOperation.java
  27. 32
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/CompositeCacheOperationSource.java
  28. 74
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultCacheExpressionRootObject.java
  29. 19
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultKeyGenerator.java
  30. 46
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java
  31. 8
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/KeyGenerator.java
  32. 48
      org.springframework.context/src/main/java/org/springframework/cache/interceptor/LazyParamAwareEvaluationContext.java
  33. 65
      org.springframework.context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java
  34. 62
      org.springframework.context/src/main/java/org/springframework/cache/support/CompositeCacheManager.java
  35. 9
      org.springframework.context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java
  36. 21
      org.springframework.context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java
  37. 14
      org.springframework.context/src/main/java/org/springframework/cache/support/ValueWrapperImpl.java
  38. 2
      org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTests.java
  39. 6
      org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java
  40. 63
      org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheManagerTests.java
  41. 2
      org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTests.java
  42. 2
      org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTests.java
  43. 2
      org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTests.java
  44. 4
      org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java
  45. 2
      org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java
  46. 4
      org.springframework.context/src/test/resources/org/springframework/cache/config/annotationDrivenCacheConfig.xml

70
org.springframework.context/src/main/java/org/springframework/cache/Cache.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -16,73 +16,67 @@ @@ -16,73 +16,67 @@
package org.springframework.cache;
/**
* Interface that defines the common cache operations.
*
*
* <b>Note:</b> Due to the generic use of caching, it is recommended that
* implementations allow storage of <tt>null</tt> values (for example to
* cache methods that return null).
*
* cache methods that return <code>null</code>).
*
* @author Costin Leau
* @since 3.1
*/
public interface Cache {
/**
* A (wrapper) object representing a cache value.
*/
interface ValueWrapper {
/**
* Returns the actual value in the cache.
*
* @return cache value
*/
Object get();
}
/**
* Returns the cache name.
*
* @return the cache name.
* Return the cache name.
*/
String getName();
/**
* Returns the the native, underlying cache provider.
*
* @return the underlying native cache provider.
* Return the the underlying native cache provider.
*/
Object getNativeCache();
/**
* Returns the value to which this cache maps the specified key. Returns
* <tt>null</tt> if the cache contains no mapping for this key.
*
* Return the value to which this cache maps the specified key. Returns
* <code>null</code> if the cache contains no mapping for this key.
* @param key key whose associated value is to be returned.
* @return the value to which this cache maps the specified key, or
* <tt>null</tt> if the cache contains no mapping for this key.
* @return the value to which this cache maps the specified key,
* or <code>null</code> if the cache contains no mapping for this key
*/
ValueWrapper get(Object key);
/**
* Associates the specified value with the specified key in this cache.
* If the cache previously contained a mapping for this key, the old
* Associate the specified value with the specified key in this cache.
* <p>If the cache previously contained a mapping for this key, the old
* value is replaced by the specified value.
*
* @param key key with which the specified value is to be associated.
* @param value value to be associated with the specified key.
* @param key the key with which the specified value is to be associated
* @param value the value to be associated with the specified key
*/
void put(Object key, Object value);
/**
* Evicts the mapping for this key from this cache if it is present.
*
* @param key key whose mapping is to be removed from the cache.
* Evict the mapping for this key from this cache if it is present.
* @param key the key whose mapping is to be removed from the cache
*/
void evict(Object key);
/**
* Removes all mappings from the cache.
* Remove all mappings from the cache.
*/
void clear();
}
/**
* A (wrapper) object representing a cache value.
*/
interface ValueWrapper {
/**
* Return the actual value in the cache.
*/
Object get();
}
}

21
org.springframework.context/src/main/java/org/springframework/cache/CacheManager.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -18,26 +18,25 @@ package org.springframework.cache; @@ -18,26 +18,25 @@ package org.springframework.cache;
import java.util.Collection;
/**
* Entity managing {@link Cache}s.
*
* A manager for a set of {@link Cache}s.
*
* @author Costin Leau
* @since 3.1
*/
public interface CacheManager {
/**
* Returns the cache associated with the given name.
*
* @param name cache identifier - cannot be null
* @return associated cache or null if none is found
* Return the cache associated with the given name.
* @param name cache identifier (must not be <code>null</code>)
* @return associated cache, or <code>null</code> if none is found
*/
Cache getCache(String name);
/**
* Returns a collection of the caches known by this cache manager.
*
* @return names of caches known by the cache manager.
* Return a collection of the caches known by this cache manager.
* @return names of caches known by the cache manager.
*/
Collection<String> getCacheNames();
}

25
org.springframework.context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -37,29 +37,28 @@ import org.springframework.util.Assert; @@ -37,29 +37,28 @@ import org.springframework.util.Assert;
* This class may also serve as base class for a custom CacheOperationSource.
*
* @author Costin Leau
* @since 3.1
*/
@SuppressWarnings("serial")
public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperationSource implements
Serializable {
public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperationSource
implements Serializable {
private final boolean publicMethodsOnly;
private final Set<CacheAnnotationParser> annotationParsers;
/**
* Create a default AnnotationCacheOperationSource, supporting
* public methods that carry the <code>Cacheable</code> and <code>CacheEvict</code>
* annotations.
* Create a default AnnotationCacheOperationSource, supporting public methods
* that carry the <code>Cacheable</code> and <code>CacheEvict</code> annotations.
*/
public AnnotationCacheOperationSource() {
this(true);
}
/**
* Create a custom AnnotationCacheOperationSource, supporting
* public methods that carry the <code>Cacheable</code> and
* <code>CacheEvict</code> annotations.
*
* Create a default AnnotationCacheOperationSource, supporting public methods
* that carry the <code>Cacheable</code> and <code>CacheEvict</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)
@ -67,7 +66,7 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati @@ -67,7 +66,7 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati
public AnnotationCacheOperationSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = new LinkedHashSet<CacheAnnotationParser>(1);
this.annotationParsers.add(new SpringCachingAnnotationParser());
this.annotationParsers.add(new SpringCacheAnnotationParser());
}
/**
@ -82,6 +81,7 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati @@ -82,6 +81,7 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati
this.annotationParsers = parsers;
}
@Override
protected CacheOperation findCacheOperation(Class<?> clazz) {
return determineCacheOperation(clazz);
@ -120,4 +120,5 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati @@ -120,4 +120,5 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati
protected boolean allowPublicMethodsOnly() {
return this.publicMethodsOnly;
}
}
}

4
org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheAnnotationParser.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -28,6 +28,7 @@ import org.springframework.cache.interceptor.CacheOperation; @@ -28,6 +28,7 @@ import org.springframework.cache.interceptor.CacheOperation;
* {@link Cacheable} or {@link CacheEvict}.
*
* @author Costin Leau
* @since 3.1
*/
public interface CacheAnnotationParser {
@ -43,4 +44,5 @@ public interface CacheAnnotationParser { @@ -43,4 +44,5 @@ public interface CacheAnnotationParser {
* @see AnnotationCacheOperationSource#determineCacheOperation
*/
CacheOperation parseCacheAnnotation(AnnotatedElement ae);
}

19
org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheEvict.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -26,10 +26,11 @@ import java.lang.annotation.Target; @@ -26,10 +26,11 @@ import java.lang.annotation.Target;
/**
* Annotation indicating that a method (or all methods on a class) trigger(s)
* a cache invalidate operation.
*
*
* @author Costin Leau
* @since 3.1
*/
@Target( { ElementType.METHOD, ElementType.TYPE })
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@ -44,24 +45,22 @@ public @interface CacheEvict { @@ -44,24 +45,22 @@ public @interface CacheEvict {
/**
* Spring Expression Language (SpEL) attribute for computing the key dynamically.
* <p/>
* Default is "" meaning all method parameters are considered as a key.
* <p>Default is "", meaning all method parameters are considered as a key.
*/
String key() default "";
/**
* Spring Expression Language (SpEL) attribute used for conditioning the method caching.
* <p/>
* Default is "" meaning the method is always cached.
* <p>Default is "", meaning the method is always cached.
*/
String condition() default "";
/**
* Whether or not all the entries inside the cache(s) are removed or not. By
* default, only the value under the associated key is removed.
*
* Note that specifying setting this parameter to true and specifying a
* <p>Note that specifying setting this parameter to true and specifying a
* {@link CacheKey key} is not allowed.
*/
boolean allEntries() default false;
}
}

12
org.springframework.context/src/main/java/org/springframework/cache/annotation/Cacheable.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -25,10 +25,12 @@ import java.lang.annotation.Target; @@ -25,10 +25,12 @@ import java.lang.annotation.Target;
/**
* Annotation indicating that a method (or all the methods on a class) can be cached.
* The method arguments and signature are used for computing the key while the return instance
* as the cache value.
*
*
* <p>The method arguments and signature are used for computing the key while the
* returned instance is used as the cache value.
*
* @author Costin Leau
* @since 3.1
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@ -55,4 +57,4 @@ public @interface Cacheable { @@ -55,4 +57,4 @@ public @interface Cacheable {
*/
String condition() default "";
}
}

68
org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java vendored

@ -0,0 +1,68 @@ @@ -0,0 +1,68 @@
/*
* Copyright 2002-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 org.springframework.cache.interceptor.CacheEvictOperation;
import org.springframework.cache.interceptor.CacheOperation;
import org.springframework.cache.interceptor.CacheUpdateOperation;
import org.springframework.core.annotation.AnnotationUtils;
/**
* Strategy implementation for parsing Spring's {@link Cacheable} and {@link CacheEvict} annotations.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
@SuppressWarnings("serial")
public class SpringCacheAnnotationParser implements CacheAnnotationParser, Serializable {
public CacheOperation parseCacheAnnotation(AnnotatedElement ae) {
Cacheable update = AnnotationUtils.getAnnotation(ae, Cacheable.class);
if (update != null) {
return parseCacheableAnnotation(ae, update);
}
CacheEvict evict = AnnotationUtils.getAnnotation(ae, CacheEvict.class);
if (evict != null) {
return parseEvictAnnotation(ae, evict);
}
return null;
}
CacheUpdateOperation parseCacheableAnnotation(AnnotatedElement ae, Cacheable ann) {
CacheUpdateOperation cuo = new CacheUpdateOperation();
cuo.setCacheNames(ann.value());
cuo.setCondition(ann.condition());
cuo.setKey(ann.key());
cuo.setName(ae.toString());
return cuo;
}
CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, CacheEvict ann) {
CacheEvictOperation ceo = new CacheEvictOperation();
ceo.setCacheNames(ann.value());
ceo.setCondition(ann.condition());
ceo.setKey(ann.key());
ceo.setCacheWide(ann.allEntries());
ceo.setName(ae.toString());
return ceo;
}
}

84
org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCachingAnnotationParser.java vendored

@ -1,84 +0,0 @@ @@ -1,84 +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.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import org.springframework.cache.interceptor.CacheEvictOperation;
import org.springframework.cache.interceptor.CacheOperation;
import org.springframework.cache.interceptor.CacheUpdateOperation;
/**
* Strategy implementation for parsing Spring's {@link Cacheable} and {@link CacheEvict} annotations.
*
* @author Costin Leau
*/
@SuppressWarnings("serial")
public class SpringCachingAnnotationParser implements CacheAnnotationParser, Serializable {
public CacheOperation parseCacheAnnotation(AnnotatedElement ae) {
Cacheable update = findAnnotation(ae, Cacheable.class);
if (update != null) {
return parseCacheableAnnotation(ae, update);
}
CacheEvict invalidate = findAnnotation(ae, CacheEvict.class);
if (invalidate != null) {
return parseEvictAnnotation(ae, invalidate);
}
return null;
}
private <T extends Annotation> T findAnnotation(AnnotatedElement ae, Class<T> annotationType) {
T ann = ae.getAnnotation(annotationType);
if (ann == null) {
for (Annotation metaAnn : ae.getAnnotations()) {
ann = metaAnn.annotationType().getAnnotation(annotationType);
if (ann != null) {
break;
}
}
}
return ann;
}
CacheUpdateOperation parseCacheableAnnotation(AnnotatedElement target, Cacheable ann) {
CacheUpdateOperation dcud = new CacheUpdateOperation();
dcud.setCacheNames(ann.value());
dcud.setCondition(ann.condition());
dcud.setKey(ann.key());
dcud.setName(target.toString());
return dcud;
}
CacheEvictOperation parseEvictAnnotation(AnnotatedElement target, CacheEvict ann) {
CacheEvictOperation dcid = new CacheEvictOperation();
dcid.setCacheNames(ann.value());
dcid.setCondition(ann.condition());
dcid.setKey(ann.key());
dcid.setCacheWide(ann.allEntries());
dcid.setName(target.toString());
return dcid;
}
}

125
org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -17,86 +17,129 @@ @@ -17,86 +17,129 @@
package org.springframework.cache.concurrent;
import java.io.Serializable;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.springframework.cache.Cache;
import org.springframework.cache.support.DefaultValueWrapper;
import org.springframework.cache.support.ValueWrapperImpl;
/**
* Simple {@link Cache} implementation based on the JDK 1.5+
* java.util.concurrent package. Useful for testing or simple caching scenarios.
* Simple {@link Cache} implementation based on the core JDK
* <code>java.util.concurrent</code> package.
*
* <p>Useful for testing or simple caching scenarios, typically in combination
* with {@link org.springframework.cache.support.SimpleCacheManager} or
* dynamically through {@link ConcurrentMapCacheManager}.
*
* <p><b>Note:</b> As {@link ConcurrentHashMap} (the default implementation used)
* does not allow for <code>null</code> values to be stored, this class will replace
* them with a predefined internal object. This behavior can be changed through the
* {@link #ConcurrentMapCache(String, ConcurrentMap, boolean)} constructor.
*
* <b>Note:</b>As {@link ConcurrentHashMap} (the default implementation used) does not allow null values to be stored
* this class will replace them with a predefined, internal object. This behaviour can be changed through the {@link #ConcurrentMapCache(ConcurrentMap, String, boolean)}
* constructor.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
public class ConcurrentMapCache implements Cache {
private static class NullHolder implements Serializable {
private static final long serialVersionUID = 1L;
}
private static final Object NULL_HOLDER = new NullHolder();
private final ConcurrentMap store;
private final String name;
private final ConcurrentMap<Object, Object> store;
private final boolean allowNullValues;
public ConcurrentMapCache() {
this("");
}
/**
* Create a new ConcurrentMapCache with the specified name.
* @param name the name of the cache
*/
public ConcurrentMapCache(String name) {
this(new ConcurrentHashMap(), name, true);
this(name, new ConcurrentHashMap<Object, Object>(), true);
}
/**
* Create a new ConcurrentMapCache with the specified name.
* @param name the name of the cache
*/
public ConcurrentMapCache(String name, boolean allowNullValues) {
this(name, new ConcurrentHashMap<Object, Object>(), allowNullValues);
}
public ConcurrentMapCache(ConcurrentMap delegate, String name, boolean allowNullValues) {
this.store = delegate;
/**
* Create a new ConcurrentMapCache with the specified name and the
* given internal ConcurrentMap to use.
* @param name the name of the cache
* @param store the ConcurrentMap to use as an internal store
* @param allowNullValues whether to allow <code>null</code> values
* (adapting them to an internal null holder value)
*/
public ConcurrentMapCache(String name, ConcurrentMap<Object, Object> store, boolean allowNullValues) {
this.name = name;
this.store = store;
this.allowNullValues = allowNullValues;
}
public String getName() {
return name;
}
public boolean getAllowNullValues() {
return allowNullValues;
public String getName() {
return this.name;
}
public ConcurrentMap getNativeCache() {
return store;
return this.store;
}
public void clear() {
store.clear();
public boolean isAllowNullValues() {
return this.allowNullValues;
}
public ValueWrapper get(Object key) {
Object v = store.get(key);
return (v != null ? new DefaultValueWrapper(filterNull(v)) : null);
Object value = this.store.get(key);
return (value != null ? new ValueWrapperImpl(fromStoreValue(value)) : null);
}
public void put(Object key, Object value) {
if (allowNullValues && value == null) {
Map map = store;
map.put(key, NULL_HOLDER);
} else {
store.put(key, value);
}
this.store.put(key, toStoreValue(value));
}
public void evict(Object key) {
store.remove(key);
this.store.remove(key);
}
protected Object filterNull(Object val) {
if (allowNullValues && val == NULL_HOLDER) {
public void clear() {
this.store.clear();
}
/**
* Convert the given value from the internal store to a user value
* returned from the get method (adapting <code>null</code>).
* @param userValue the store value
* @return the value to return to the user
*/
protected Object fromStoreValue(Object storeValue) {
if (this.allowNullValues && storeValue == NULL_HOLDER) {
return null;
}
return val;
return storeValue;
}
/**
* Convert the given user value, as passed into the put method,
* to a value in the internal store (adapting <code>null</code>).
* @param userValue the given user value
* @return the value to store
*/
protected Object toStoreValue(Object userValue) {
if (this.allowNullValues && userValue == null) {
return NULL_HOLDER;
}
return userValue;
}
}
private static class NullHolder implements Serializable {
}
}

77
org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheFactoryBean.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -24,45 +24,78 @@ import org.springframework.beans.factory.InitializingBean; @@ -24,45 +24,78 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;
/**
* Factory bean for easy configuration of {@link ConcurrentMapCache} through Spring.
*
* {@link FactoryBean} for easy configuration of a {@link ConcurrentMapCache}
* when used within a Spring container. Can be configured through bean properties;
* uses the assigned Spring bean name as the default cache name.
*
* <p>Useful for testing or simple caching scenarios, typically in combination
* with {@link org.springframework.cache.support.SimpleCacheManager} or
* dynamically through {@link ConcurrentMapCacheManager}.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
public class ConcurrentMapCacheFactoryBean implements FactoryBean<ConcurrentMapCache>, BeanNameAware,
InitializingBean {
public class ConcurrentMapCacheFactoryBean
implements FactoryBean<ConcurrentMapCache>, BeanNameAware, InitializingBean {
private String name = "";
private ConcurrentMapCache cache;
private ConcurrentMap store;
private ConcurrentMap<Object, Object> store;
public void afterPropertiesSet() {
cache = (store == null ? new ConcurrentMapCache(name) : new ConcurrentMapCache(store, name, true));
}
private boolean allowNullValues = true;
private ConcurrentMapCache cache;
public ConcurrentMapCache getObject() throws Exception {
return cache;
/**
* Specify the name of the cache.
* <p>Default is "" (empty String).
*/
public void setName(String name) {
this.name = name;
}
public Class<?> getObjectType() {
return (cache != null ? cache.getClass() : ConcurrentMapCache.class);
/**
* Specify the ConcurrentMap to use as an internal store
* (possibly pre-populated).
* <p>Default is a standard {@link java.util.concurrent.ConcurrentHashMap}.
*/
public void setStore(ConcurrentMap<Object, Object> store) {
this.store = store;
}
public boolean isSingleton() {
return true;
/**
* Set whether to allow <code>null</code> values
* (adapting them to an internal null holder value).
* <p>Default is "true".
*/
public void setAllowNullValues(boolean allowNullValues) {
this.allowNullValues = allowNullValues;
}
public void setBeanName(String beanName) {
if (!StringUtils.hasText(name)) {
if (!StringUtils.hasLength(this.name)) {
setName(beanName);
}
}
public void setName(String name) {
this.name = name;
public void afterPropertiesSet() {
this.cache = (this.store != null ? new ConcurrentMapCache(this.name, this.store, this.allowNullValues) :
new ConcurrentMapCache(this.name, this.allowNullValues));
}
public void setStore(ConcurrentMap store) {
this.store = store;
public ConcurrentMapCache getObject() {
return this.cache;
}
}
public Class<?> getObjectType() {
return ConcurrentMapCache.class;
}
public boolean isSingleton() {
return true;
}
}

101
org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java vendored

@ -0,0 +1,101 @@ @@ -0,0 +1,101 @@
/*
* Copyright 2002-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.concurrent;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
/**
* {@link CacheManager} implementation that lazily builds {@link ConcurrentMapCache}
* instances for each {@link #getCache} request. Also supports a 'static' mode where
* the set of cache names is pre-defined through {@link #setCacheNames}, with no
* dynamic creation of further cache regions at runtime.
*
* @author Juergen Hoeller
* @since 3.1
*/
public class ConcurrentMapCacheManager implements CacheManager {
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
private boolean dynamic = true;
/**
* Construct a dynamic ConcurrentMapCacheManager,
* lazily creating cache instances as they are being requested.
*/
public ConcurrentMapCacheManager() {
}
/**
* Construct a static ConcurrentMapCacheManager,
* managing caches for the specified cache names only.
*/
public ConcurrentMapCacheManager(String... cacheNames) {
setCacheNames(Arrays.asList(cacheNames));
}
/**
* Specify the set of cache names for this CacheManager's 'static' mode.
* <p>The number of caches and their names will be fixed after a call to this method,
* with no creation of further cache regions at runtime.
*/
public void setCacheNames(Collection<String> cacheNames) {
if (cacheNames != null) {
for (String name : cacheNames) {
this.cacheMap.put(name, createConcurrentMapCache(name));
}
this.dynamic = false;
}
}
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(this.cacheMap.keySet());
}
public Cache getCache(String name) {
Cache cache = this.cacheMap.get(name);
if (cache == null && this.dynamic) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (cache == null) {
cache = createConcurrentMapCache(name);
this.cacheMap.put(name, cache);
}
}
}
return cache;
}
/**
* Create a new ConcurrentMapCache instance for the specified cache name.
* @param name the name of the cache
* @return the ConcurrentMapCache (or a decorator thereof)
*/
protected Cache createConcurrentMapCache(String name) {
return new ConcurrentMapCache(name);
}
}

17
org.springframework.context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -16,7 +16,7 @@ @@ -16,7 +16,7 @@
package org.springframework.cache.config;
import static org.springframework.context.annotation.AnnotationConfigUtils.*;
import org.w3c.dom.Element;
import org.springframework.aop.config.AopNamespaceUtils;
import org.springframework.beans.factory.config.BeanDefinition;
@ -29,7 +29,8 @@ import org.springframework.beans.factory.xml.ParserContext; @@ -29,7 +29,8 @@ import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.cache.annotation.AnnotationCacheOperationSource;
import org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor;
import org.springframework.cache.interceptor.CacheInterceptor;
import org.w3c.dom.Element;
import static org.springframework.context.annotation.AnnotationConfigUtils.*;
/**
* {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
@ -43,6 +44,7 @@ import org.w3c.dom.Element; @@ -43,6 +44,7 @@ import org.w3c.dom.Element;
* will result in class-based proxies being created.
*
* @author Costin Leau
* @since 3.1
*/
class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser {
@ -111,7 +113,7 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser @@ -111,7 +113,7 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
if (!parserContext.getRegistry().containsBeanDefinition(CACHE_ADVISOR_BEAN_NAME)) {
Object eleSource = parserContext.extractSource(element);
// Create the CacheDefinitionSource definition.
// Create the CacheOperationSource definition.
RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationCacheOperationSource.class);
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
@ -122,14 +124,14 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser @@ -122,14 +124,14 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
interceptorDef.setSource(eleSource);
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registerCacheManagerProperty(element, interceptorDef);
interceptorDef.getPropertyValues().add("cacheDefinitionSources", new RuntimeBeanReference(sourceName));
interceptorDef.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(sourceName));
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// Create the CacheAdvisor definition.
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryCacheOperationSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
advisorDef.getPropertyValues().add("cacheDefinitionSource", new RuntimeBeanReference(sourceName));
advisorDef.getPropertyValues().add("cacheOperationSource", new RuntimeBeanReference(sourceName));
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
if (element.hasAttribute("order")) {
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
@ -145,4 +147,5 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser @@ -145,4 +147,5 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
}
}
}
}
}

4
org.springframework.context/src/main/java/org/springframework/cache/config/CacheNamespaceHandler.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -26,10 +26,12 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport; @@ -26,10 +26,12 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
* Spring cache management facilities.
*
* @author Costin Leau
* @since 3.1
*/
public class CacheNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenCacheBeanDefinitionParser());
}
}

36
org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -21,53 +21,57 @@ import net.sf.ehcache.Element; @@ -21,53 +21,57 @@ import net.sf.ehcache.Element;
import net.sf.ehcache.Status;
import org.springframework.cache.Cache;
import org.springframework.cache.support.DefaultValueWrapper;
import org.springframework.cache.support.ValueWrapperImpl;
import org.springframework.util.Assert;
/**
* {@link Cache} implementation on top of an {@link Ehcache} instance.
*
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
public class EhCacheCache implements Cache {
private final Ehcache cache;
/**
* Creates a {@link EhCacheCache} instance.
*
* Create an {@link EhCacheCache} instance.
* @param ehcache backing Ehcache instance
*/
public EhCacheCache(Ehcache ehcache) {
Assert.notNull(ehcache, "non null ehcache required");
Assert.notNull(ehcache, "Ehcache must not be null");
Status status = ehcache.getStatus();
Assert.isTrue(Status.STATUS_ALIVE.equals(status), "an 'alive' ehcache is required - current cache is "
+ status.toString());
Assert.isTrue(Status.STATUS_ALIVE.equals(status),
"An 'alive' Ehcache is required - current cache is " + status.toString());
this.cache = ehcache;
}
public String getName() {
return cache.getName();
return this.cache.getName();
}
public Ehcache getNativeCache() {
return cache;
return this.cache;
}
public void clear() {
cache.removeAll();
this.cache.removeAll();
}
public ValueWrapper get(Object key) {
Element element = cache.get(key);
return (element != null ? new DefaultValueWrapper(element.getObjectValue()) : null);
Element element = this.cache.get(key);
return (element != null ? new ValueWrapperImpl(element.getObjectValue()) : null);
}
public void put(Object key, Object value) {
cache.put(new Element(key, value));
this.cache.put(new Element(key, value));
}
public void evict(Object key) {
cache.remove(key);
this.cache.remove(key);
}
}
}

54
org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -27,55 +27,53 @@ import org.springframework.cache.support.AbstractCacheManager; @@ -27,55 +27,53 @@ import org.springframework.cache.support.AbstractCacheManager;
import org.springframework.util.Assert;
/**
* CacheManager backed by an Ehcache {@link net.sf.ehcache.CacheManager}.
*
* CacheManager backed by an EhCache {@link net.sf.ehcache.CacheManager}.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
public class EhCacheCacheManager extends AbstractCacheManager {
private net.sf.ehcache.CacheManager cacheManager;
/**
* Set the backing EhCache {@link net.sf.ehcache.CacheManager}.
*/
public void setCacheManager(net.sf.ehcache.CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
protected Collection<Cache> loadCaches() {
Assert.notNull(cacheManager, "a backing Ehcache cache manager is required");
Status status = cacheManager.getStatus();
Assert.notNull(this.cacheManager, "A backing EhCache CacheManager is required");
Status status = this.cacheManager.getStatus();
Assert.isTrue(Status.STATUS_ALIVE.equals(status),
"an 'alive' Ehcache cache manager is required - current cache is " + status.toString());
"An 'alive' EhCache CacheManager is required - current cache is " + status.toString());
String[] names = cacheManager.getCacheNames();
String[] names = this.cacheManager.getCacheNames();
Collection<Cache> caches = new LinkedHashSet<Cache>(names.length);
for (String name : names) {
caches.add(new EhCacheCache(cacheManager.getEhcache(name)));
caches.add(new EhCacheCache(this.cacheManager.getEhcache(name)));
}
return caches;
}
@Override
public Cache getCache(String name) {
Cache cache = super.getCache(name);
if (cache == null) {
// check the Ehcache cache again
// in case the cache was added at runtime
Ehcache ehcache = cacheManager.getEhcache(name);
// check the EhCache cache again
// (in case the cache was added at runtime)
Ehcache ehcache = this.cacheManager.getEhcache(name);
if (ehcache != null) {
// reinitialize cache map
afterPropertiesSet();
cache = super.getCache(name);
cache = new EhCacheCache(ehcache);
addCache(cache);
}
}
return cache;
}
/**
* Sets the backing Ehcache {@link net.sf.ehcache.CacheManager}.
*
* @param cacheManager backing Ehcache {@link net.sf.ehcache.CacheManager}
*/
public void setCacheManager(net.sf.ehcache.CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
}
}

14
org.springframework.context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -41,9 +41,9 @@ import org.springframework.util.ObjectUtils; @@ -41,9 +41,9 @@ import org.springframework.util.ObjectUtils;
* <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
* @since 3.1
*/
public abstract class AbstractFallbackCacheOperationSource implements CacheOperationSource {
@ -67,6 +67,7 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera @@ -67,6 +67,7 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
*/
final Map<Object, CacheOperation> attributeCache = new ConcurrentHashMap<Object, CacheOperation>();
/**
* Determine the caching attribute for this method invocation.
* <p>Defaults to the class's caching attribute if no method attribute is found.
@ -157,6 +158,7 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera @@ -157,6 +158,7 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
return null;
}
/**
* Subclasses need to implement this to return the caching attribute
* for the given method, if any.
@ -183,8 +185,9 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera @@ -183,8 +185,9 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
return false;
}
/**
* Default cache key for the CacheOperationDefinition cache.
* Default cache key for the CacheOperation cache.
*/
private static class DefaultCacheKey {
@ -215,4 +218,5 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera @@ -215,4 +218,5 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
return this.method.hashCode() * 29 + (this.targetClass != null ? this.targetClass.hashCode() : 0);
}
}
}
}

15
org.springframework.context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -25,27 +25,29 @@ import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor; @@ -25,27 +25,29 @@ import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
* cache advice bean for methods that are cacheable.
*
* @author Costin Leau
* @since 3.1
*/
@SuppressWarnings("serial")
public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
private CacheOperationSource cacheDefinitionSource;
private CacheOperationSource cacheOperationSource;
private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
@Override
protected CacheOperationSource getCacheOperationSource() {
return cacheDefinitionSource;
return cacheOperationSource;
}
};
/**
* 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(CacheOperationSource cacheDefinitionSource) {
this.cacheDefinitionSource = cacheDefinitionSource;
public void setCacheOperationSource(CacheOperationSource cacheOperationSource) {
this.cacheOperationSource = cacheOperationSource;
}
/**
@ -59,4 +61,5 @@ public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryP @@ -59,4 +61,5 @@ public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryP
public Pointcut getPointcut() {
return this.pointcut;
}
}
}

173
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -25,12 +25,11 @@ import java.util.concurrent.Callable; @@ -25,12 +25,11 @@ import java.util.concurrent.Callable;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.KeyGenerator;
import org.springframework.cache.support.DefaultKeyGenerator;
import org.springframework.expression.EvaluationContext;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@ -57,6 +56,8 @@ import org.springframework.util.StringUtils; @@ -57,6 +56,8 @@ import org.springframework.util.StringUtils;
* and <code>CacheDefinitionSource</code> are serializable.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
public abstract class CacheAspectSupport implements InitializingBean {
@ -64,26 +65,82 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -64,26 +65,82 @@ public abstract class CacheAspectSupport implements InitializingBean {
private CacheManager cacheManager;
private CacheOperationSource cacheDefinitionSource;
private CacheOperationSource cacheOperationSource;
private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
private KeyGenerator keyGenerator = new DefaultKeyGenerator();
private volatile boolean initialized = false;
private boolean initialized = false;
/**
* Set the CacheManager that this cache aspect should delegate to.
*/
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
/**
* Return the CacheManager that this cache aspect delegates to.
*/
public CacheManager getCacheManager() {
return this.cacheManager;
}
/**
* Set multiple cache definition sources which are used to find the cache
* attributes. Will build a CompositeCachingDefinitionSource for the given sources.
*/
public void setCacheOperationSources(CacheOperationSource... cacheDefinitionSources) {
Assert.notEmpty(cacheDefinitionSources);
this.cacheOperationSource = (cacheDefinitionSources.length > 1 ?
new CompositeCacheOperationSource(cacheDefinitionSources) : cacheDefinitionSources[0]);
}
/**
* Set the CacheOperationSource for this cache aspect,
* resolving applicable cache operations from annotations or the like.
*/
public void setCacheOperationSource(CacheOperationSource cacheOperationSource) {
this.cacheOperationSource = cacheOperationSource;
}
/**
* Return the CacheOperationSource for this cache aspect.
*/
public CacheOperationSource getCacheOperationSource() {
return this.cacheOperationSource;
}
/**
* Set the KeyGenerator for this cache aspect.
* Default is {@link DefaultKeyGenerator}.
*/
public void setKeyGenerator(KeyGenerator keyGenerator) {
this.keyGenerator = keyGenerator;
}
/**
* Return the KeyGenerator for this cache aspect,
*/
public KeyGenerator getKeyGenerator() {
return this.keyGenerator;
}
public void afterPropertiesSet() {
if (this.cacheManager == null) {
throw new IllegalStateException("Setting the property 'cacheManager' is required");
throw new IllegalStateException("'cacheManager' is required");
}
if (this.cacheDefinitionSource == null) {
if (this.cacheOperationSource == null) {
throw new IllegalStateException("Either 'cacheDefinitionSource' or 'cacheDefinitionSources' is required: "
+ "If there are no cacheable methods, then don't use a cache aspect.");
}
initialized = true;
this.initialized = true;
}
/**
* Convenience method to return a String representation of this Method
* for use in logging. Can be overridden in subclasses to provide a
@ -98,62 +155,29 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -98,62 +155,29 @@ public abstract class CacheAspectSupport implements InitializingBean {
return ClassUtils.getQualifiedMethodName(specificMethod);
}
public CacheManager getCacheManager() {
return cacheManager;
}
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
public CacheOperationSource getCacheDefinitionSource() {
return cacheDefinitionSource;
}
public KeyGenerator getKeyGenerator() {
return keyGenerator;
}
public void setKeyGenerator(KeyGenerator keyGenerator) {
this.keyGenerator = keyGenerator;
}
/**
* Set multiple cache definition sources which are used to find the cache
* attributes. Will build a CompositeCachingDefinitionSource for the given sources.
*/
public void setCacheDefinitionSources(CacheOperationSource... cacheDefinitionSources) {
Assert.notEmpty(cacheDefinitionSources);
this.cacheDefinitionSource = (cacheDefinitionSources.length > 1 ? new CompositeCacheOperationSource(
cacheDefinitionSources) : cacheDefinitionSources[0]);
}
protected Collection<Cache> getCaches(CacheOperation operation) {
Set<String> cacheNames = operation.getCacheNames();
Collection<Cache> caches = new ArrayList<Cache>(cacheNames.size());
for (String cacheName : cacheNames) {
Cache cache = cacheManager.getCache(cacheName);
Cache cache = this.cacheManager.getCache(cacheName);
if (cache == null) {
throw new IllegalArgumentException("Cannot find cache named [" + cacheName + "] for " + operation);
}
caches.add(cache);
}
return caches;
}
protected CacheOperationContext getOperationContext(CacheOperation operation, Method method, Object[] args,
Object target, Class<?> targetClass) {
return new CacheOperationContext(operation, method, args, target, targetClass);
}
protected Object execute(Callable<Object> invocation, Object target, Method method, Object[] args) throws Exception {
// check whether aspect is enabled
// to cope with cases where the AJ is pulled in automatically
if (!initialized) {
if (!this.initialized) {
return invocation.call();
}
@ -161,15 +185,13 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -161,15 +185,13 @@ public abstract class CacheAspectSupport implements InitializingBean {
// get backing class
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(target);
if (targetClass == null && target != null) {
targetClass = target.getClass();
}
final CacheOperation cacheOp = getCacheDefinitionSource().getCacheOperation(method, targetClass);
final CacheOperation cacheOp = getCacheOperationSource().getCacheOperation(method, targetClass);
Object retVal = null;
// analyze caching information
if (cacheOp != null) {
CacheOperationContext context = getOperationContext(cacheOp, method, args, target, targetClass);
@ -179,11 +201,9 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -179,11 +201,9 @@ public abstract class CacheAspectSupport implements InitializingBean {
// check operation
if (cacheOp instanceof CacheUpdateOperation) {
Object key = context.generateKey();
if (log) {
logger.trace("Computed cache key " + key + " for definition " + cacheOp);
}
if (key == null) {
throw new IllegalArgumentException(
"Null key returned for cache definition (maybe you are using named params on classes without debug info?) "
@ -196,7 +216,6 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -196,7 +216,6 @@ public abstract class CacheAspectSupport implements InitializingBean {
for (Iterator<Cache> iterator = caches.iterator(); iterator.hasNext() && !cacheHit;) {
Cache cache = iterator.next();
Cache.ValueWrapper wrapper = cache.get(key);
if (wrapper != null) {
cacheHit = true;
retVal = wrapper.get();
@ -209,12 +228,12 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -209,12 +228,12 @@ public abstract class CacheAspectSupport implements InitializingBean {
+ method);
}
retVal = invocation.call();
// update all caches
for (Cache cache : caches) {
cache.put(key, retVal);
}
} else {
}
else {
if (log) {
logger.trace("Key " + key + " found in cache, returning value " + retVal);
}
@ -234,10 +253,11 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -234,10 +253,11 @@ public abstract class CacheAspectSupport implements InitializingBean {
if (evictOp.isCacheWide()) {
cache.clear();
if (log) {
logger.trace("Invalidating entire cache for definition " + cacheOp + " on method "
+ method);
logger.trace("Invalidating entire cache for definition " + cacheOp +
" on method " + method);
}
} else {
}
else {
// check key
if (key == null) {
key = context.generateKey();
@ -250,9 +270,9 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -250,9 +270,9 @@ public abstract class CacheAspectSupport implements InitializingBean {
}
}
}
return retVal;
} else {
}
else {
if (log) {
logger.trace("Cache condition failed on method " + method + " for definition " + cacheOp);
}
@ -262,19 +282,22 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -262,19 +282,22 @@ public abstract class CacheAspectSupport implements InitializingBean {
return invocation.call();
}
protected class CacheOperationContext {
private CacheOperation operation;
private final CacheOperation operation;
private final Collection<Cache> caches;
private final Object target;
private final Method method;
private final Object[] args;
// context passed around to avoid multiple creations
private final EvaluationContext evalContext;
private final KeyGenerator keyGenerator = CacheAspectSupport.this.keyGenerator;
public CacheOperationContext(CacheOperation operation, Method method, Object[] args, Object target,
Class<?> targetClass) {
this.operation = operation;
@ -286,39 +309,27 @@ public abstract class CacheAspectSupport implements InitializingBean { @@ -286,39 +309,27 @@ public abstract class CacheAspectSupport implements InitializingBean {
this.evalContext = evaluator.createEvaluationContext(caches, method, args, target, targetClass);
}
/**
* Evaluates the definition condition.
*
* @param operation
* @return
*/
protected boolean hasConditionPassed() {
if (StringUtils.hasText(operation.getCondition())) {
return evaluator.condition(operation.getCondition(), method, evalContext);
if (StringUtils.hasText(this.operation.getCondition())) {
return evaluator.condition(this.operation.getCondition(), this.method, this.evalContext);
}
return true;
}
/**
* Computes the key for the given caching definition.
*
* @param operation
* @param method
* method being invoked
* @param objects
* arguments passed during the method invocation
* Computes the key for the given caching operation.
* @return generated key (null if none can be generated)
*/
protected Object generateKey() {
if (StringUtils.hasText(operation.getKey())) {
return evaluator.key(operation.getKey(), method, evalContext);
if (StringUtils.hasText(this.operation.getKey())) {
return evaluator.key(this.operation.getKey(), this.method, this.evalContext);
}
return keyGenerator.extract(target, method, args);
return keyGenerator.extract(this.target, this.method, this.args);
}
protected Collection<Cache> getCaches() {
return caches;
return this.caches;
}
}
}
}

17
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -17,27 +17,28 @@ @@ -17,27 +17,28 @@
package org.springframework.cache.interceptor;
/**
* Class describing an 'evict' operation.
*
* Class describing a cache 'evict' operation.
*
* @author Costin Leau
* @since 3.1
*/
public class CacheEvictOperation extends CacheOperation {
private boolean cacheWide = false;
public boolean isCacheWide() {
return cacheWide;
}
public void setCacheWide(boolean cacheWide) {
this.cacheWide = cacheWide;
}
public boolean isCacheWide() {
return this.cacheWide;
}
@Override
protected StringBuilder getOperationDescription() {
StringBuilder sb = super.getOperationDescription();
sb.append(",");
sb.append(cacheWide);
sb.append(this.cacheWide);
return sb;
}
}

101
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheExpressionRootObject.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -20,53 +20,62 @@ import java.lang.reflect.Method; @@ -20,53 +20,62 @@ import java.lang.reflect.Method;
import java.util.Collection;
import org.springframework.cache.Cache;
import org.springframework.util.Assert;
/**
* Interface describing the root object used during the expression evaluation.
*
* Class describing the root object used during the expression evaluation.
*
* @author Costin Leau
* @since 3.1
*/
interface CacheExpressionRootObject {
/**
* Returns the name of the method being cached.
*
* @return name of the cached method.
*/
String getMethodName();
/**
* Returns the method being cached.
*
* @return method being cached
*/
Method getMethod();
/**
* Returns the parameters for this invocation.
*
* @return params for this invocation.
*/
Object[] getParams();
/**
* Returns the target instance being cached.
*
* @return target instance
*/
Object getTarget();
/**
* Returns the target class.
*
* @return target class
*/
Class<?> getTargetClass();
/**
* Returns the caches against which the method is executed.
*
* @return current cache
*/
Collection<Cache> getCaches();
class CacheExpressionRootObject {
private final Collection<Cache> caches;
private final Method method;
private final Object[] args;
private final Object target;
private final Class<?> targetClass;
public CacheExpressionRootObject(
Collection<Cache> caches, Method method, Object[] args, Object target, Class<?> targetClass) {
Assert.notNull(method, "Method is required");
Assert.notNull(targetClass, "targetClass is required");
this.method = method;
this.target = target;
this.targetClass = targetClass;
this.args = args;
this.caches = caches;
}
public Collection<Cache> getCaches() {
return this.caches;
}
public Method getMethod() {
return this.method;
}
public String getMethodName() {
return this.method.getName();
}
public Object[] getArgs() {
return this.args;
}
public Object getTarget() {
return this.target;
}
public Class<?> getTargetClass() {
return this.targetClass;
}
}

21
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheInterceptor.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -23,6 +23,8 @@ import java.util.concurrent.Callable; @@ -23,6 +23,8 @@ import java.util.concurrent.Callable;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.ReflectionUtils;
/**
* AOP Alliance MethodInterceptor for declarative cache
* management using the common Spring caching infrastructure
@ -34,8 +36,10 @@ import org.aopalliance.intercept.MethodInvocation; @@ -34,8 +36,10 @@ import org.aopalliance.intercept.MethodInvocation;
* in the correct order.
*
* <p>CacheInterceptors are thread-safe.
*
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
@SuppressWarnings("serial")
public class CacheInterceptor extends CacheAspectSupport implements MethodInterceptor, Serializable {
@ -44,19 +48,18 @@ public class CacheInterceptor extends CacheAspectSupport implements MethodInterc @@ -44,19 +48,18 @@ public class CacheInterceptor extends CacheAspectSupport implements MethodInterc
Method method = invocation.getMethod();
Callable<Object> aopAllianceInvocation = new Callable<Object>() {
public Object call() throws Exception {
try {
return invocation.proceed();
} catch (Throwable th) {
if (th instanceof Exception) {
throw (Exception) th;
}
throw (Error) th;
}
catch (Throwable ex) {
ReflectionUtils.rethrowException(ex);
return null;
}
}
};
return execute(aopAllianceInvocation, invocation.getThis(), method, invocation.getArguments());
}
}
}

10
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -115,13 +115,13 @@ public abstract class CacheOperation { @@ -115,13 +115,13 @@ public abstract class CacheOperation {
protected StringBuilder getOperationDescription() {
StringBuilder result = new StringBuilder();
result.append("CacheDefinition[");
result.append(name);
result.append(this.name);
result.append("] caches=");
result.append(cacheNames);
result.append(this.cacheNames);
result.append(" | condition='");
result.append(condition);
result.append(this.condition);
result.append("' | key='");
result.append(key);
result.append(this.key);
result.append("'");
return result;
}

17
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSource.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -18,24 +18,25 @@ package org.springframework.cache.interceptor; @@ -18,24 +18,25 @@ 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
* @since 3.1
*/
public interface CacheOperationSource {
/**
* 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 the cache operation definition for this method,
* or <code>null</code> if the method is not cacheable.
* @param method the method to introspect
* @param targetClass the target class (may be <code>null</code>,
* in which case the declaring class of the method must be used)
* @return {@link CacheOperation} the matching cache operation,
* or <code>null</code> if none found
*/
CacheOperation getCacheOperation(Method method, Class<?> targetClass);
}

10
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -23,10 +23,11 @@ import org.springframework.aop.support.StaticMethodMatcherPointcut; @@ -23,10 +23,11 @@ import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.util.ObjectUtils;
/**
* Inner class that implements a Pointcut that matches if the underlying
* {@link CacheOperationSource} has an attribute for a given method.
* A Pointcut that matches if the underlying {@link CacheOperationSource}
* has an attribute for a given method.
*
* @author Costin Leau
* @since 3.1
*/
@SuppressWarnings("serial")
abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@ -65,4 +66,5 @@ abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut @@ -65,4 +66,5 @@ abstract class CacheOperationSourcePointcut extends StaticMethodMatcherPointcut
* To be implemented by subclasses.
*/
protected abstract CacheOperationSource getCacheOperationSource();
}
}

4
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheProxyFactoryBean.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -50,7 +50,7 @@ public class CacheProxyFactoryBean extends AbstractSingletonProxyFactoryBean { @@ -50,7 +50,7 @@ public class CacheProxyFactoryBean extends AbstractSingletonProxyFactoryBean {
* @param cacheDefinitionSources cache definition sources
*/
public void setCacheDefinitionSources(CacheOperationSource... cacheDefinitionSources) {
this.cachingInterceptor.setCacheDefinitionSources(cacheDefinitionSources);
this.cachingInterceptor.setCacheOperationSources(cacheDefinitionSources);
}
}

7
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheUpdateOperation.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -17,9 +17,10 @@ @@ -17,9 +17,10 @@
package org.springframework.cache.interceptor;
/**
* Class describing an 'update' operation.
*
* Class describing a cache 'update' operation.
*
* @author Costin Leau
* @since 3.1
*/
public class CacheUpdateOperation extends CacheOperation {

32
org.springframework.context/src/main/java/org/springframework/cache/interceptor/CompositeCacheOperationSource.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -24,40 +24,42 @@ import org.springframework.util.Assert; @@ -24,40 +24,42 @@ import org.springframework.util.Assert;
/**
* Composite {@link CacheOperationSource} implementation that iterates
* over a given array of {@link CacheOperationSource} instances.
*
*
* @author Costin Leau
* @since 3.1
*/
@SuppressWarnings("serial")
public class CompositeCacheOperationSource implements CacheOperationSource, Serializable {
private final CacheOperationSource[] cacheDefinitionSources;
private final CacheOperationSource[] cacheOperationSources;
/**
* Create a new CompositeCachingDefinitionSource for the given sources.
* @param cacheDefinitionSourcess the CacheDefinitionSource instances to combine
* Create a new CompositeCacheOperationSource for the given sources.
* @param cacheOperationSources the CacheOperationSource instances to combine
*/
public CompositeCacheOperationSource(CacheOperationSource[] cacheDefinitionSources) {
Assert.notNull(cacheDefinitionSources, "cacheDefinitionSource array must not be null");
this.cacheDefinitionSources = cacheDefinitionSources;
public CompositeCacheOperationSource(CacheOperationSource... cacheOperationSources) {
Assert.notEmpty(cacheOperationSources, "cacheOperationSources array must not be empty");
this.cacheOperationSources = cacheOperationSources;
}
/**
* Return the CacheDefinitionSource instances that this
* CompositeCachingDefinitionSource combines.
* Return the CacheOperationSource instances that this CompositeCachingDefinitionSource combines.
*/
public final CacheOperationSource[] getCacheDefinitionSources() {
return this.cacheDefinitionSources;
public final CacheOperationSource[] getCacheOperationSources() {
return this.cacheOperationSources;
}
public CacheOperation getCacheOperation(Method method, Class<?> targetClass) {
for (CacheOperationSource source : cacheDefinitionSources) {
for (CacheOperationSource source : this.cacheOperationSources) {
CacheOperation definition = source.getCacheOperation(method, targetClass);
if (definition != null) {
return definition;
}
}
return null;
}
}
}

74
org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultCacheExpressionRootObject.java vendored

@ -1,74 +0,0 @@ @@ -1,74 +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.util.Collection;
import org.springframework.cache.Cache;
import org.springframework.util.Assert;
/**
* Default implementation of expression root object.
*
* @author Costin Leau
*/
public class DefaultCacheExpressionRootObject implements CacheExpressionRootObject {
private final Object target;
private final Class<?> targetClass;
private final String methodName;
private final Method method;
private final Collection<Cache> caches;
private final Object[] args;
public DefaultCacheExpressionRootObject(Collection<Cache> caches, Method method, Object[] args,
Object target, Class<?> targetClass) {
Assert.notNull(method, "method is required");
Assert.notNull(targetClass, "targetClass is required");
this.method = method;
this.methodName = method.getName();
this.target = target;
this.targetClass = targetClass;
this.args = args;
this.caches = caches;
}
public String getMethodName() {
return methodName;
}
public Collection<Cache> getCaches() {
return caches;
}
public Method getMethod() {
return method;
}
public Object[] getParams() {
return args;
}
public Object getTarget() {
return target;
}
public Class<?> getTargetClass() {
return targetClass;
}
}

19
org.springframework.context/src/main/java/org/springframework/cache/support/DefaultKeyGenerator.java → org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultKeyGenerator.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -14,17 +14,19 @@ @@ -14,17 +14,19 @@
* limitations under the License.
*/
package org.springframework.cache.support;
package org.springframework.cache.interceptor;
import java.lang.reflect.Method;
import org.springframework.cache.KeyGenerator;
import org.springframework.cache.interceptor.KeyGenerator;
/**
* Default key generator. Returns 0 if no param is given, the param itself if only one is given or a hash code computed
* from all given params hash code. Uses a constant (53) for null objects.
*
* Default key generator. Returns 0 if no param is given, the param itself if
* only one is given or a hash code computed from all given params hash code.
* Uses a constant (53) for <code>null</code> objects.
*
* @author Costin Leau
* @since 3.1
*/
public class DefaultKeyGenerator implements KeyGenerator {
@ -32,17 +34,14 @@ public class DefaultKeyGenerator implements KeyGenerator { @@ -32,17 +34,14 @@ public class DefaultKeyGenerator implements KeyGenerator {
if (params.length == 1) {
return (params[0] == null ? 53 : params[0]);
}
if (params.length == 0) {
return 0;
}
int hashCode = 17;
for (Object object : params) {
hashCode = 31 * hashCode + (object == null ? 53 : object.hashCode());
}
return Integer.valueOf(hashCode);
}
}

46
org.springframework.context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -27,51 +27,55 @@ import org.springframework.core.ParameterNameDiscoverer; @@ -27,51 +27,55 @@ import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
/**
* Utility class handling the SpEL expression parsing.
* Meant to be used as a reusable, thread-safe component.
*
* Performs internal caching for performance reasons.
*
*
* <p>Performs internal caching for performance reasons.
*
* @author Costin Leau
* @since 3.1
*/
class ExpressionEvaluator {
private SpelExpressionParser parser = new SpelExpressionParser();
// shared param discoverer since it caches data internally
private ParameterNameDiscoverer paramNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
private Map<Method, Expression> conditionCache = new ConcurrentHashMap<Method, Expression>();
private Map<Method, Expression> keyCache = new ConcurrentHashMap<Method, Expression>();
private Map<Method, Method> targetMethodCache = new ConcurrentHashMap<Method, Method>();
EvaluationContext createEvaluationContext(Collection<Cache> caches, Method method, Object[] args,
Object target, Class<?> targetClass) {
DefaultCacheExpressionRootObject rootObject = new DefaultCacheExpressionRootObject(caches, method, args,
target, targetClass);
StandardEvaluationContext evaluationContext = new LazyParamAwareEvaluationContext(rootObject,
paramNameDiscoverer, method, args, targetClass, targetMethodCache);
return evaluationContext;
public EvaluationContext createEvaluationContext(
Collection<Cache> caches, Method method, Object[] args, Object target, Class<?> targetClass) {
CacheExpressionRootObject rootObject =
new CacheExpressionRootObject(caches, method, args, target, targetClass);
return new LazyParamAwareEvaluationContext(rootObject,
this.paramNameDiscoverer, method, args, targetClass, this.targetMethodCache);
}
boolean condition(String conditionExpression, Method method, EvaluationContext evalContext) {
Expression condExp = conditionCache.get(method);
public boolean condition(String conditionExpression, Method method, EvaluationContext evalContext) {
Expression condExp = this.conditionCache.get(method);
if (condExp == null) {
condExp = parser.parseExpression(conditionExpression);
conditionCache.put(method, condExp);
condExp = this.parser.parseExpression(conditionExpression);
this.conditionCache.put(method, condExp);
}
return condExp.getValue(evalContext, boolean.class);
}
Object key(String keyExpression, Method method, EvaluationContext evalContext) {
Expression keyExp = keyCache.get(method);
public Object key(String keyExpression, Method method, EvaluationContext evalContext) {
Expression keyExp = this.keyCache.get(method);
if (keyExp == null) {
keyExp = parser.parseExpression(keyExpression);
keyCache.put(method, keyExp);
keyExp = this.parser.parseExpression(keyExpression);
this.keyCache.put(method, keyExp);
}
return keyExp.getValue(evalContext);
}
}
}

8
org.springframework.context/src/main/java/org/springframework/cache/KeyGenerator.java → org.springframework.context/src/main/java/org/springframework/cache/interceptor/KeyGenerator.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -14,17 +14,19 @@ @@ -14,17 +14,19 @@
* limitations under the License.
*/
package org.springframework.cache;
package org.springframework.cache.interceptor;
import java.lang.reflect.Method;
/**
* Cache 'key' extractor. Used for creating a key based on the given method
* (used as context) and its parameters.
*
*
* @author Costin Leau
* @since 3.1
*/
public interface KeyGenerator {
Object extract(Object target, Method method, Object... params);
}

48
org.springframework.context/src/main/java/org/springframework/cache/interceptor/LazyParamAwareEvaluationContext.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -28,22 +28,28 @@ import org.springframework.util.ObjectUtils; @@ -28,22 +28,28 @@ import org.springframework.util.ObjectUtils;
* Evaluation context class that adds a method parameters as SpEL variables,
* in a lazy manner. The lazy nature eliminates unneeded parsing of classes
* byte code for parameter discovery.
*
* To limit the creation of objects, an ugly constructor is used (rather then a
* dedicated 'closure'-like class for deferred execution).
*
*
* <p>To limit the creation of objects, an ugly constructor is used (rather then
* a dedicated 'closure'-like class for deferred execution).
*
* @author Costin Leau
* @since 3.1
*/
class LazyParamAwareEvaluationContext extends StandardEvaluationContext {
private final ParameterNameDiscoverer paramDiscoverer;
private final Method method;
private final Object[] args;
private Class<?> targetClass;
private Map<Method, Method> methodCache;
private final Class<?> targetClass;
private final Map<Method, Method> methodCache;
private boolean paramLoaded = false;
LazyParamAwareEvaluationContext(Object rootObject, ParameterNameDiscoverer paramDiscoverer, Method method,
Object[] args, Class<?> targetClass, Map<Method, Method> methodCache) {
super(rootObject);
@ -55,6 +61,7 @@ class LazyParamAwareEvaluationContext extends StandardEvaluationContext { @@ -55,6 +61,7 @@ class LazyParamAwareEvaluationContext extends StandardEvaluationContext {
this.methodCache = methodCache;
}
/**
* Load the param information only when needed.
*/
@ -64,42 +71,41 @@ class LazyParamAwareEvaluationContext extends StandardEvaluationContext { @@ -64,42 +71,41 @@ class LazyParamAwareEvaluationContext extends StandardEvaluationContext {
if (variable != null) {
return variable;
}
if (!paramLoaded) {
paramLoaded = true;
if (!this.paramLoaded) {
loadArgsAsVariables();
this.paramLoaded = true;
variable = super.lookupVariable(name);
}
return variable;
}
private void loadArgsAsVariables() {
// shortcut if no args need to be loaded
if (ObjectUtils.isEmpty(args)) {
if (ObjectUtils.isEmpty(this.args)) {
return;
}
Method targetMethod = methodCache.get(method);
Method targetMethod = this.methodCache.get(this.method);
if (targetMethod == null) {
targetMethod = AopUtils.getMostSpecificMethod(method, targetClass);
targetMethod = AopUtils.getMostSpecificMethod(this.method, this.targetClass);
if (targetMethod == null) {
targetMethod = method;
targetMethod = this.method;
}
methodCache.put(method, targetMethod);
this.methodCache.put(this.method, targetMethod);
}
// save arguments as indexed variables
for (int i = 0; i < args.length; i++) {
super.setVariable("p" + i, args[i]);
for (int i = 0; i < this.args.length; i++) {
setVariable("p" + i, this.args[i]);
}
String[] parameterNames = paramDiscoverer.getParameterNames(targetMethod);
String[] parameterNames = this.paramDiscoverer.getParameterNames(targetMethod);
// save parameter names (if discovered)
if (parameterNames != null) {
for (int i = 0; i < parameterNames.length; i++) {
super.setVariable(parameterNames[i], args[i]);
setVariable(parameterNames[i], this.args[i]);
}
}
}
}
}

65
org.springframework.context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -29,57 +29,50 @@ import org.springframework.cache.CacheManager; @@ -29,57 +29,50 @@ import org.springframework.cache.CacheManager;
import org.springframework.util.Assert;
/**
* Abstract base class implementing the common CacheManager methods. Useful for 'static' environments where the
* backing caches do not change.
*
* Abstract base class implementing the common CacheManager methods.
* Useful for 'static' environments where the backing caches do not change.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
public abstract class AbstractCacheManager implements CacheManager, InitializingBean {
// fast lookup by name map
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
private Collection<String> names;
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
public void afterPropertiesSet() {
Collection<Cache> cacheSet = loadCaches();
private Set<String> cacheNames = new LinkedHashSet<String>();
Assert.notEmpty(cacheSet);
caches.clear();
public void afterPropertiesSet() {
Collection<Cache> caches = loadCaches();
Assert.notEmpty(caches, "loadCaches must not return an empty Collection");
this.cacheMap.clear();
// preserve the initial order of the cache names
Set<String> cacheNames = new LinkedHashSet<String>(cacheSet.size());
for (Cache cache : cacheSet) {
caches.put(cache.getName(), cache);
cacheNames.add(cache.getName());
for (Cache cache : caches) {
this.cacheMap.put(cache.getName(), cache);
this.cacheNames.add(cache.getName());
}
names = Collections.unmodifiableSet(cacheNames);
}
/**
* Loads the caches into the cache manager. Occurs at startup.
* The returned collection should not be null.
*
* @param caches the collection of caches handled by the manager
*/
protected abstract Collection<Cache> loadCaches();
/**
* Returns the internal cache map.
*
* @return internal cache map
*/
protected final ConcurrentMap<String, Cache> getCacheMap() {
return caches;
protected final void addCache(Cache cache) {
this.cacheMap.put(cache.getName(), cache);
this.cacheNames.add(cache.getName());
}
public Cache getCache(String name) {
return caches.get(name);
return this.cacheMap.get(name);
}
public Collection<String> getCacheNames() {
return names;
return Collections.unmodifiableSet(this.cacheNames);
}
}
/**
* Load the caches for this cache manager. Occurs at startup.
* The returned collection must not be null.
*/
protected abstract Collection<Cache> loadCaches();
}

62
org.springframework.context/src/main/java/org/springframework/cache/support/CompositeCacheManager.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -29,57 +29,59 @@ import org.springframework.util.Assert; @@ -29,57 +29,59 @@ import org.springframework.util.Assert;
/**
* Composite {@link CacheManager} implementation that iterates
* over a given collection of {@link CacheManager} instances.
*
*
* Allows {@link NoOpCacheManager} to be automatically added to the list for handling
* the cache declarations without a backing store.
*
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
public class CompositeCacheManager implements InitializingBean, CacheManager {
private List<CacheManager> cacheManagers;
private boolean noOpManager = false;
private boolean fallbackToNoOpCache = false;
public void setCacheManagers(Collection<CacheManager> cacheManagers) {
Assert.notEmpty(cacheManagers, "cacheManagers Collection must not be empty");
this.cacheManagers = new ArrayList<CacheManager>();
this.cacheManagers.addAll(cacheManagers);
}
/**
* Indicate whether a {@link NoOpCacheManager} should be added at the end of the manager lists.
* In this case, any <code>getCache</code> requests not handled by the configured cache managers will
* be automatically handled by the {@link NoOpCacheManager} (and hence never return <code>null</code>).
*/
public void setFallbackToNoOpCache(boolean fallbackToNoOpCache) {
this.fallbackToNoOpCache = fallbackToNoOpCache;
}
public void afterPropertiesSet() {
if (noOpManager) {
cacheManagers.add(new NoOpCacheManager());
if (this.fallbackToNoOpCache) {
this.cacheManagers.add(new NoOpCacheManager());
}
}
public Cache getCache(String name) {
Cache cache = null;
for (CacheManager cacheManager : cacheManagers) {
cache = cacheManager.getCache(name);
for (CacheManager cacheManager : this.cacheManagers) {
Cache cache = cacheManager.getCache(name);
if (cache != null) {
return cache;
}
}
return cache;
return null;
}
public Collection<String> getCacheNames() {
List<String> names = new ArrayList<String>();
for (CacheManager manager : cacheManagers) {
for (CacheManager manager : this.cacheManagers) {
names.addAll(manager.getCacheNames());
}
return Collections.unmodifiableCollection(names);
return Collections.unmodifiableList(names);
}
public void setCacheManagers(Collection<CacheManager> cacheManagers) {
Assert.notEmpty(cacheManagers, "non-null/empty array required");
this.cacheManagers = new ArrayList<CacheManager>();
this.cacheManagers.addAll(cacheManagers);
}
/**
* Indicates whether a {@link NoOpCacheManager} will be added at the end of the manager lists.
* Any cache requests not handled by the configured cache managers will be automatically handled
* by the {@link NoOpCacheManager}.
*
* @param add whether a {@link NoOpCacheManager} instance will be added or not
*/
public void setAddNoOpCache(boolean add) {
this.noOpManager = add;
}
}
}

9
org.springframework.context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java vendored

@ -29,11 +29,12 @@ import org.springframework.cache.CacheManager; @@ -29,11 +29,12 @@ import org.springframework.cache.CacheManager;
/**
* A basic, no operation {@link CacheManager} implementation suitable for disabling caching,
* typically used for backing cache declarations without an actual backing store.
*
* Will simply accept any items into the cache not actually storing them.
*
* @see CompositeCacheManager
*
* <p>Will simply accept any items into the cache not actually storing them.
*
* @author Costin Leau
* @since 3.1
* @see CompositeCacheManager
*/
public class NoOpCacheManager implements CacheManager {

21
org.springframework.context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2010-2011 the original author or authors.
* Copyright 2002-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.
@ -21,21 +21,26 @@ import java.util.Collection; @@ -21,21 +21,26 @@ import java.util.Collection;
import org.springframework.cache.Cache;
/**
* Simple cache manager working against a given collection of caches. Useful for testing or simple
* caching declarations.
*
* Simple cache manager working against a given collection of caches.
* Useful for testing or simple caching declarations.
*
* @author Costin Leau
* @since 3.1
*/
public class SimpleCacheManager extends AbstractCacheManager {
private Collection<Cache> caches;
/**
* Specify the collection of Cache instances to use for this CacheManager.
*/
public void setCaches(Collection<Cache> caches) {
this.caches = caches;
}
@Override
protected Collection<Cache> loadCaches() {
return caches;
return this.caches;
}
public void setCaches(Collection<Cache> caches) {
this.caches = caches;
}
}

14
org.springframework.context/src/main/java/org/springframework/cache/support/DefaultValueWrapper.java → org.springframework.context/src/main/java/org/springframework/cache/support/ValueWrapperImpl.java vendored

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2011 the original author or authors.
* Copyright 2002-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.
@ -19,19 +19,21 @@ package org.springframework.cache.support; @@ -19,19 +19,21 @@ package org.springframework.cache.support;
import org.springframework.cache.Cache.ValueWrapper;
/**
* Default implementation for {@link org.springframework.cache.Cache.ValueWrapper}.
*
* Straightforward implementation of {@link org.springframework.cache.Cache.ValueWrapper}.
*
* @author Costin Leau
* @since 3.1
*/
public class DefaultValueWrapper implements ValueWrapper {
public class ValueWrapperImpl implements ValueWrapper {
private final Object value;
public DefaultValueWrapper(Object value) {
public ValueWrapperImpl(Object value) {
this.value = value;
}
public Object get() {
return value;
return this.value;
}
}

2
org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTest.java → org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTests.java vendored

@ -24,7 +24,7 @@ import org.junit.Before; @@ -24,7 +24,7 @@ import org.junit.Before;
import org.junit.Test;
import org.springframework.cache.support.NoOpCacheManager;
public class NoOpCacheManagerTest {
public class NoOpCacheManagerTests {
private CacheManager manager;

6
org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTest.java → org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java vendored

@ -20,16 +20,16 @@ import java.util.concurrent.ConcurrentHashMap; @@ -20,16 +20,16 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.springframework.cache.Cache;
import org.springframework.cache.vendor.AbstractNativeCacheTest;
import org.springframework.cache.vendor.AbstractNativeCacheTests;
/**
* @author Costin Leau
*/
public class ConcurrentCacheTest extends AbstractNativeCacheTest<ConcurrentMap<Object, Object>> {
public class ConcurrentCacheTests extends AbstractNativeCacheTests<ConcurrentMap<Object, Object>> {
@Override
protected Cache createCache(ConcurrentMap<Object, Object> nativeCache) {
return new ConcurrentMapCache(nativeCache, CACHE_NAME, true);
return new ConcurrentMapCache(CACHE_NAME, nativeCache, true);
}
@Override

63
org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheManagerTests.java vendored

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
/*
* Copyright 2002-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.concurrent;
import org.junit.Test;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import static org.junit.Assert.*;
/**
* @author Juergen Hoeller
*/
public class ConcurrentMapCacheManagerTests {
@Test
public void testDynamicMode() {
CacheManager cm = new ConcurrentMapCacheManager();
Cache cache1 = cm.getCache("c1");
assertTrue(cache1 instanceof ConcurrentMapCache);
Cache cache1again = cm.getCache("c1");
assertSame(cache1again, cache1);
Cache cache2 = cm.getCache("c2");
assertTrue(cache2 instanceof ConcurrentMapCache);
Cache cache2again = cm.getCache("c2");
assertSame(cache2again, cache2);
Cache cache3 = cm.getCache("c3");
assertTrue(cache3 instanceof ConcurrentMapCache);
Cache cache3again = cm.getCache("c3");
assertSame(cache3again, cache3);
}
@Test
public void testStaticMode() {
ConcurrentMapCacheManager cm = new ConcurrentMapCacheManager("c1", "c2");
Cache cache1 = cm.getCache("c1");
assertTrue(cache1 instanceof ConcurrentMapCache);
Cache cache1again = cm.getCache("c1");
assertSame(cache1again, cache1);
Cache cache2 = cm.getCache("c2");
assertTrue(cache2 instanceof ConcurrentMapCache);
Cache cache2again = cm.getCache("c2");
assertSame(cache2again, cache2);
Cache cache3 = cm.getCache("c3");
assertNull(cache3);
}
}

2
org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTest.java → org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTests.java vendored

@ -31,7 +31,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; @@ -31,7 +31,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
*
* @author Costin Leau
*/
public abstract class AbstractAnnotationTest {
public abstract class AbstractAnnotationTests {
protected ApplicationContext ctx;

2
org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTest.java → org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTests.java vendored

@ -20,7 +20,7 @@ package org.springframework.cache.config; @@ -20,7 +20,7 @@ package org.springframework.cache.config;
/**
* @author Costin Leau
*/
public class AnnotationNamespaceDrivenTest extends AbstractAnnotationTest {
public class AnnotationNamespaceDrivenTests extends AbstractAnnotationTests {
@Override
protected String getConfig() {

2
org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTest.java → org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTests.java vendored

@ -20,7 +20,7 @@ package org.springframework.cache.config; @@ -20,7 +20,7 @@ package org.springframework.cache.config;
/**
* @author Costin Leau
*/
public class AnnotationTest extends AbstractAnnotationTest {
public class AnnotationTests extends AbstractAnnotationTests {
@Override
protected String getConfig() {

4
org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTest.java → org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java vendored

@ -22,14 +22,14 @@ import net.sf.ehcache.Element; @@ -22,14 +22,14 @@ import net.sf.ehcache.Element;
import org.junit.Test;
import org.springframework.cache.Cache;
import org.springframework.cache.vendor.AbstractNativeCacheTest;
import org.springframework.cache.vendor.AbstractNativeCacheTests;
/**
* Integration test for EhCache cache.
*
* @author Costin Leau
*/
public class EhCacheCacheTest extends AbstractNativeCacheTest<Ehcache> {
public class EhCacheCacheTests extends AbstractNativeCacheTests<Ehcache> {
@Override
protected Ehcache createNativeCache() throws Exception {

2
org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTest.java → org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java vendored

@ -27,7 +27,7 @@ import org.springframework.cache.Cache; @@ -27,7 +27,7 @@ import org.springframework.cache.Cache;
*
* @author Costin Leau
*/
public abstract class AbstractNativeCacheTest<T> {
public abstract class AbstractNativeCacheTests<T> {
protected T nativeCache;
protected Cache cache;

4
org.springframework.context/src/test/resources/org/springframework/cache/config/annotationDrivenCacheConfig.xml vendored

@ -17,11 +17,11 @@ @@ -17,11 +17,11 @@
<bean id="cacheInterceptor" class="org.springframework.cache.interceptor.CacheInterceptor">
<property name="cacheManager" ref="cacheManager"/>
<property name="cacheDefinitionSources" ref="annotationSource"/>
<property name="cacheOperationSources" ref="annotationSource"/>
</bean>
<bean id="advisor" class="org.springframework.cache.interceptor.BeanFactoryCacheOperationSourceAdvisor">
<property name="cacheDefinitionSource" ref="annotationSource"/>
<property name="cacheOperationSource" ref="annotationSource"/>
<property name="adviceBeanName" value="cacheInterceptor"/>
</bean>

Loading…
Cancel
Save