diff --git a/org.springframework.context/src/main/java/org/springframework/cache/Cache.java b/org.springframework.context/src/main/java/org/springframework/cache/Cache.java
index b37030dbf0a..b31afda05fe 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/Cache.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/Cache.java
@@ -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 @@
package org.springframework.cache;
-
/**
* Interface that defines the common cache operations.
- *
+ *
* Note: Due to the generic use of caching, it is recommended that
* implementations allow storage of null values (for example to
- * cache methods that return null).
- *
+ * cache methods that return null).
+ *
* @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
- * null if the cache contains no mapping for this key.
- *
+ * Return the value to which this cache maps the specified key. Returns
+ * null 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
- * null if the cache contains no mapping for this key.
+ * @return the value to which this cache maps the specified key,
+ * or null 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.
+ *
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();
-}
\ No newline at end of file
+
+
+ /**
+ * A (wrapper) object representing a cache value.
+ */
+ interface ValueWrapper {
+
+ /**
+ * Return the actual value in the cache.
+ */
+ Object get();
+ }
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/CacheManager.java b/org.springframework.context/src/main/java/org/springframework/cache/CacheManager.java
index 268e9c3a409..186f188cdf7 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/CacheManager.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/CacheManager.java
@@ -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;
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 null)
+ * @return associated cache, or null 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 getCacheNames();
+
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java b/org.springframework.context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java
index a8ef94fbd31..05f9d8a3620 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/annotation/AnnotationCacheOperationSource.java
@@ -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;
* 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 annotationParsers;
+
/**
- * Create a default AnnotationCacheOperationSource, supporting
- * public methods that carry the Cacheable and CacheEvict
- * annotations.
+ * Create a default AnnotationCacheOperationSource, supporting public methods
+ * that carry the Cacheable and CacheEvict annotations.
*/
public AnnotationCacheOperationSource() {
this(true);
}
/**
- * Create a custom AnnotationCacheOperationSource, supporting
- * public methods that carry the Cacheable and
- * CacheEvict annotations.
- *
+ * Create a default AnnotationCacheOperationSource, supporting public methods
+ * that carry the Cacheable and CacheEvict 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
public AnnotationCacheOperationSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
this.annotationParsers = new LinkedHashSet(1);
- this.annotationParsers.add(new SpringCachingAnnotationParser());
+ this.annotationParsers.add(new SpringCacheAnnotationParser());
}
/**
@@ -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
protected boolean allowPublicMethodsOnly() {
return this.publicMethodsOnly;
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheAnnotationParser.java b/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheAnnotationParser.java
index aab6ce72554..b016f3009cd 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheAnnotationParser.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheAnnotationParser.java
@@ -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;
* {@link Cacheable} or {@link CacheEvict}.
*
* @author Costin Leau
+ * @since 3.1
*/
public interface CacheAnnotationParser {
@@ -43,4 +44,5 @@ public interface CacheAnnotationParser {
* @see AnnotationCacheOperationSource#determineCacheOperation
*/
CacheOperation parseCacheAnnotation(AnnotatedElement ae);
+
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheEvict.java b/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheEvict.java
index dbc109e131e..6414d17efd8 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheEvict.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheEvict.java
@@ -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;
/**
* 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 {
/**
* Spring Expression Language (SpEL) attribute for computing the key dynamically.
- *
- * Default is "" meaning all method parameters are considered as a key.
+ * 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.
- *
- * Default is "" meaning the method is always cached.
+ * 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
+ *
Note that specifying setting this parameter to true and specifying a
* {@link CacheKey key} is not allowed.
*/
boolean allEntries() default false;
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/annotation/Cacheable.java b/org.springframework.context/src/main/java/org/springframework/cache/annotation/Cacheable.java
index a5d007c0570..132352dbaee 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/annotation/Cacheable.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/annotation/Cacheable.java
@@ -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;
/**
* 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.
- *
+ *
+ *
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 {
*/
String condition() default "";
-}
\ No newline at end of file
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java b/org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java
new file mode 100644
index 00000000000..df99b7f73ec
--- /dev/null
+++ b/org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java
@@ -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;
+ }
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCachingAnnotationParser.java b/org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCachingAnnotationParser.java
deleted file mode 100644
index 8a5eef1d0d6..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/cache/annotation/SpringCachingAnnotationParser.java
+++ /dev/null
@@ -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 findAnnotation(AnnotatedElement ae, Class 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;
- }
-}
\ No newline at end of file
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java b/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java
index 15e72162c64..945f920ef63 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java
@@ -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 @@
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
+ * java.util.concurrent package.
+ *
+ * Useful for testing or simple caching scenarios, typically in combination
+ * with {@link org.springframework.cache.support.SimpleCacheManager} or
+ * dynamically through {@link ConcurrentMapCacheManager}.
+ *
+ *
Note: As {@link ConcurrentHashMap} (the default implementation used)
+ * does not allow for null 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.
*
- * Note: 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 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(), 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(), 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 null values
+ * (adapting them to an internal null holder value)
+ */
+ public ConcurrentMapCache(String name, ConcurrentMap 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 null).
+ * @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 null).
+ * @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;
}
-}
\ No newline at end of file
+
+
+ private static class NullHolder implements Serializable {
+ }
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheFactoryBean.java b/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheFactoryBean.java
index 6e6a501dd6e..c7a9474ecdd 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheFactoryBean.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheFactoryBean.java
@@ -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;
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.
+ *
+ * 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, BeanNameAware,
- InitializingBean {
+public class ConcurrentMapCacheFactoryBean
+ implements FactoryBean, BeanNameAware, InitializingBean {
private String name = "";
- private ConcurrentMapCache cache;
- private ConcurrentMap store;
+ private ConcurrentMap 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.
+ * 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).
+ *
Default is a standard {@link java.util.concurrent.ConcurrentHashMap}.
+ */
+ public void setStore(ConcurrentMap store) {
+ this.store = store;
}
- public boolean isSingleton() {
- return true;
+ /**
+ * Set whether to allow null values
+ * (adapting them to an internal null holder value).
+ * 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;
}
-}
\ No newline at end of file
+
+ public Class> getObjectType() {
+ return ConcurrentMapCache.class;
+ }
+
+ public boolean isSingleton() {
+ return true;
+ }
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java b/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java
new file mode 100644
index 00000000000..2d447e6d822
--- /dev/null
+++ b/org.springframework.context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java
@@ -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 cacheMap = new ConcurrentHashMap();
+
+ 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.
+ * 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 cacheNames) {
+ if (cacheNames != null) {
+ for (String name : cacheNames) {
+ this.cacheMap.put(name, createConcurrentMapCache(name));
+ }
+ this.dynamic = false;
+ }
+ }
+
+ public Collection 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);
+ }
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java b/org.springframework.context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java
index 2b49436670d..27e05211f20 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java
@@ -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 @@
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;
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;
* 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
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
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
}
}
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/config/CacheNamespaceHandler.java b/org.springframework.context/src/main/java/org/springframework/cache/config/CacheNamespaceHandler.java
index a5e69594c05..604a9eeb3b1 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/config/CacheNamespaceHandler.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/config/CacheNamespaceHandler.java
@@ -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;
* Spring cache management facilities.
*
* @author Costin Leau
+ * @since 3.1
*/
public class CacheNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenCacheBeanDefinitionParser());
}
+
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java b/org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java
index b6d7e476bdb..21d1d822c82 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCache.java
@@ -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;
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);
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java b/org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java
index a623f918d54..65969a36931 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/ehcache/EhCacheCacheManager.java
@@ -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;
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 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 caches = new LinkedHashSet(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;
- }
-}
\ No newline at end of file
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java
index 687ec82b635..71b9f167c78 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java
@@ -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;
* 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
*/
final Map attributeCache = new ConcurrentHashMap();
+
/**
* Determine the caching attribute for this method invocation.
* Defaults to the class's caching attribute if no method attribute is found.
@@ -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
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
return this.method.hashCode() * 29 + (this.targetClass != null ? this.targetClass.hashCode() : 0);
}
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java
index 21ebfe46adc..9e51071f4c7 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/BeanFactoryCacheOperationSourceAdvisor.java
@@ -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;
* 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
public Pointcut getPointcut() {
return this.pointcut;
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java
index 82ac363ae0d..758fcb2ba1d 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java
@@ -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;
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;
* and CacheDefinitionSource 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 {
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 {
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 getCaches(CacheOperation operation) {
Set cacheNames = operation.getCacheNames();
-
Collection caches = new ArrayList(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 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 {
// 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 {
// 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 {
for (Iterator 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 {
+ 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 {
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 {
}
}
}
-
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 {
return invocation.call();
}
+
protected class CacheOperationContext {
- private CacheOperation operation;
+ private final CacheOperation operation;
+
private final Collection 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 {
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 getCaches() {
- return caches;
+ return this.caches;
}
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java
index bfbbdc4dbc2..c9c47dcd521 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheEvictOperation.java
@@ -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 @@
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;
}
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheExpressionRootObject.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheExpressionRootObject.java
index ba81aa927ee..af534a476bf 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheExpressionRootObject.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheExpressionRootObject.java
@@ -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;
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 getCaches();
+class CacheExpressionRootObject {
+
+ private final Collection caches;
+
+ private final Method method;
+
+ private final Object[] args;
+
+ private final Object target;
+
+ private final Class> targetClass;
+
+
+ public CacheExpressionRootObject(
+ Collection 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 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;
+ }
+
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheInterceptor.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheInterceptor.java
index 4fc5b6bcb07..5deefeb725d 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheInterceptor.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheInterceptor.java
@@ -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;
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;
* in the correct order.
*
* 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
Method method = invocation.getMethod();
Callable aopAllianceInvocation = new Callable() {
-
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());
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java
index 569ff2f0fcf..9a06a457bde 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperation.java
@@ -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 {
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;
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSource.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSource.java
index f22c0b11189..0d464275d9f 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSource.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSource.java
@@ -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;
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 null, in which
- * case the declaring class of the method must be used.
+ * Return the cache operation definition for this method,
+ * or null if the method is not cacheable.
+ * @param method the method to introspect
+ * @param targetClass the target class (may be null,
+ * in which case the declaring class of the method must be used)
* @return {@link CacheOperation} the matching cache operation,
* or null if none found
*/
CacheOperation getCacheOperation(Method method, Class> targetClass);
+
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java
index e519e7cb088..cfc84160471 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheOperationSourcePointcut.java
@@ -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;
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
* To be implemented by subclasses.
*/
protected abstract CacheOperationSource getCacheOperationSource();
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheProxyFactoryBean.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheProxyFactoryBean.java
index 2460c30d403..5e9bbd0d26d 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheProxyFactoryBean.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheProxyFactoryBean.java
@@ -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 {
* @param cacheDefinitionSources cache definition sources
*/
public void setCacheDefinitionSources(CacheOperationSource... cacheDefinitionSources) {
- this.cachingInterceptor.setCacheDefinitionSources(cacheDefinitionSources);
+ this.cachingInterceptor.setCacheOperationSources(cacheDefinitionSources);
}
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheUpdateOperation.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheUpdateOperation.java
index 4b11483c030..7229b1a3ae4 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheUpdateOperation.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheUpdateOperation.java
@@ -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 @@
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 {
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CompositeCacheOperationSource.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CompositeCacheOperationSource.java
index d42b8148c57..5215f551501 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CompositeCacheOperationSource.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CompositeCacheOperationSource.java
@@ -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;
/**
* 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;
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultCacheExpressionRootObject.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultCacheExpressionRootObject.java
deleted file mode 100644
index e668bc964fd..00000000000
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultCacheExpressionRootObject.java
+++ /dev/null
@@ -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 caches;
- private final Object[] args;
-
- public DefaultCacheExpressionRootObject(Collection 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 getCaches() {
- return caches;
- }
-
- public Method getMethod() {
- return method;
- }
-
- public Object[] getParams() {
- return args;
- }
-
- public Object getTarget() {
- return target;
- }
-
- public Class> getTargetClass() {
- return targetClass;
- }
-}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/support/DefaultKeyGenerator.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultKeyGenerator.java
similarity index 75%
rename from org.springframework.context/src/main/java/org/springframework/cache/support/DefaultKeyGenerator.java
rename to org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultKeyGenerator.java
index fd251f85c43..1ebe4f5ec46 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/support/DefaultKeyGenerator.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultKeyGenerator.java
@@ -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 @@
* 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 null objects.
+ *
* @author Costin Leau
+ * @since 3.1
*/
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);
}
+
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java
index 47e95a7dd68..2049ad03863 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java
@@ -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;
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.
- *
+ *
+ * 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 conditionCache = new ConcurrentHashMap();
+
private Map keyCache = new ConcurrentHashMap();
+
private Map targetMethodCache = new ConcurrentHashMap();
- EvaluationContext createEvaluationContext(Collection 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 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);
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/KeyGenerator.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/KeyGenerator.java
similarity index 84%
rename from org.springframework.context/src/main/java/org/springframework/cache/KeyGenerator.java
rename to org.springframework.context/src/main/java/org/springframework/cache/interceptor/KeyGenerator.java
index b520929bb99..45b65343070 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/KeyGenerator.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/KeyGenerator.java
@@ -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 @@
* 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);
+
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/LazyParamAwareEvaluationContext.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/LazyParamAwareEvaluationContext.java
index 60c5f75c2b1..9cb14ff7e4b 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/LazyParamAwareEvaluationContext.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/LazyParamAwareEvaluationContext.java
@@ -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;
* 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).
- *
+ *
+ * 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 methodCache;
+
+ private final Class> targetClass;
+
+ private final Map methodCache;
private boolean paramLoaded = false;
+
LazyParamAwareEvaluationContext(Object rootObject, ParameterNameDiscoverer paramDiscoverer, Method method,
Object[] args, Class> targetClass, Map methodCache) {
super(rootObject);
@@ -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 {
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]);
}
}
}
-}
\ No newline at end of file
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java b/org.springframework.context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java
index 3e393dd8085..e24fd746c02 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java
@@ -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;
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 caches = new ConcurrentHashMap();
- private Collection names;
+ private final ConcurrentMap cacheMap = new ConcurrentHashMap();
- public void afterPropertiesSet() {
- Collection cacheSet = loadCaches();
+ private Set cacheNames = new LinkedHashSet();
- Assert.notEmpty(cacheSet);
- caches.clear();
+ public void afterPropertiesSet() {
+ Collection caches = loadCaches();
+ Assert.notEmpty(caches, "loadCaches must not return an empty Collection");
+ this.cacheMap.clear();
// preserve the initial order of the cache names
- Set cacheNames = new LinkedHashSet(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 loadCaches();
-
- /**
- * Returns the internal cache map.
- *
- * @return internal cache map
- */
- protected final ConcurrentMap 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 getCacheNames() {
- return names;
+ return Collections.unmodifiableSet(this.cacheNames);
}
-}
\ No newline at end of file
+
+
+ /**
+ * Load the caches for this cache manager. Occurs at startup.
+ * The returned collection must not be null.
+ */
+ protected abstract Collection loadCaches();
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/support/CompositeCacheManager.java b/org.springframework.context/src/main/java/org/springframework/cache/support/CompositeCacheManager.java
index c0fa4a1e111..494e2fce21f 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/support/CompositeCacheManager.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/support/CompositeCacheManager.java
@@ -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;
/**
* 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 cacheManagers;
- private boolean noOpManager = false;
+
+ private boolean fallbackToNoOpCache = false;
+
+
+ public void setCacheManagers(Collection cacheManagers) {
+ Assert.notEmpty(cacheManagers, "cacheManagers Collection must not be empty");
+ this.cacheManagers = new ArrayList();
+ this.cacheManagers.addAll(cacheManagers);
+ }
+
+ /**
+ * Indicate whether a {@link NoOpCacheManager} should be added at the end of the manager lists.
+ * In this case, any getCache requests not handled by the configured cache managers will
+ * be automatically handled by the {@link NoOpCacheManager} (and hence never return null).
+ */
+ 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 getCacheNames() {
List names = new ArrayList();
- 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 cacheManagers) {
- Assert.notEmpty(cacheManagers, "non-null/empty array required");
- this.cacheManagers = new ArrayList();
- 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;
- }
-}
\ No newline at end of file
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java b/org.springframework.context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java
index aa3a3230bc6..f59f8fd6b42 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java
@@ -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
+ *
+ * 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 {
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java b/org.springframework.context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java
index 3b910fa6fb7..3350309cd8c 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/support/SimpleCacheManager.java
@@ -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;
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 caches;
+ /**
+ * Specify the collection of Cache instances to use for this CacheManager.
+ */
+ public void setCaches(Collection caches) {
+ this.caches = caches;
+ }
+
@Override
protected Collection loadCaches() {
- return caches;
+ return this.caches;
}
- public void setCaches(Collection caches) {
- this.caches = caches;
- }
}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/support/DefaultValueWrapper.java b/org.springframework.context/src/main/java/org/springframework/cache/support/ValueWrapperImpl.java
similarity index 70%
rename from org.springframework.context/src/main/java/org/springframework/cache/support/DefaultValueWrapper.java
rename to org.springframework.context/src/main/java/org/springframework/cache/support/ValueWrapperImpl.java
index a1c2e967e00..ec444700a68 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/support/DefaultValueWrapper.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/support/ValueWrapperImpl.java
@@ -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;
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;
}
+
}
diff --git a/org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTest.java b/org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTests.java
similarity index 94%
rename from org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTest.java
rename to org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTests.java
index ae1572e7c1f..2de234ebe5b 100644
--- a/org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTest.java
+++ b/org.springframework.context/src/test/java/org/springframework/cache/NoOpCacheManagerTests.java
@@ -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;
diff --git a/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTest.java b/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java
similarity index 79%
rename from org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTest.java
rename to org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java
index ba22c8c0fe8..0669bc0c080 100644
--- a/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTest.java
+++ b/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentCacheTests.java
@@ -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> {
+public class ConcurrentCacheTests extends AbstractNativeCacheTests> {
@Override
protected Cache createCache(ConcurrentMap nativeCache) {
- return new ConcurrentMapCache(nativeCache, CACHE_NAME, true);
+ return new ConcurrentMapCache(CACHE_NAME, nativeCache, true);
}
@Override
diff --git a/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheManagerTests.java b/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheManagerTests.java
new file mode 100644
index 00000000000..69b66d41ccb
--- /dev/null
+++ b/org.springframework.context/src/test/java/org/springframework/cache/concurrent/ConcurrentMapCacheManagerTests.java
@@ -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);
+ }
+
+}
diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTest.java b/org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTests.java
similarity index 95%
rename from org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTest.java
rename to org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTests.java
index 6d5ba97a625..319ae286b1c 100644
--- a/org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTest.java
+++ b/org.springframework.context/src/test/java/org/springframework/cache/config/AbstractAnnotationTests.java
@@ -31,7 +31,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
*
* @author Costin Leau
*/
-public abstract class AbstractAnnotationTest {
+public abstract class AbstractAnnotationTests {
protected ApplicationContext ctx;
diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTest.java b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTests.java
similarity index 88%
rename from org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTest.java
rename to org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTests.java
index 1348580e12d..a30838f743d 100644
--- a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTest.java
+++ b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationNamespaceDrivenTests.java
@@ -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() {
diff --git a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTest.java b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTests.java
similarity index 89%
rename from org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTest.java
rename to org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTests.java
index 1d69e2b0521..97c84e894fc 100644
--- a/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTest.java
+++ b/org.springframework.context/src/test/java/org/springframework/cache/config/AnnotationTests.java
@@ -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() {
diff --git a/org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTest.java b/org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java
similarity index 88%
rename from org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTest.java
rename to org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java
index 220ddc2f04f..e007e1f5c61 100644
--- a/org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTest.java
+++ b/org.springframework.context/src/test/java/org/springframework/cache/ehcache/EhCacheCacheTests.java
@@ -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 {
+public class EhCacheCacheTests extends AbstractNativeCacheTests {
@Override
protected Ehcache createNativeCache() throws Exception {
diff --git a/org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTest.java b/org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java
similarity index 93%
rename from org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTest.java
rename to org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java
index 45832d66cca..e4bf138c198 100644
--- a/org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTest.java
+++ b/org.springframework.context/src/test/java/org/springframework/cache/vendor/AbstractNativeCacheTests.java
@@ -27,7 +27,7 @@ import org.springframework.cache.Cache;
*
* @author Costin Leau
*/
-public abstract class AbstractNativeCacheTest {
+public abstract class AbstractNativeCacheTests {
protected T nativeCache;
protected Cache cache;
diff --git a/org.springframework.context/src/test/resources/org/springframework/cache/config/annotationDrivenCacheConfig.xml b/org.springframework.context/src/test/resources/org/springframework/cache/config/annotationDrivenCacheConfig.xml
index 167f778fe62..db0415562f9 100644
--- a/org.springframework.context/src/test/resources/org/springframework/cache/config/annotationDrivenCacheConfig.xml
+++ b/org.springframework.context/src/test/resources/org/springframework/cache/config/annotationDrivenCacheConfig.xml
@@ -17,11 +17,11 @@
-
+
-
+