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 b31afda05fe..32cedfe6de7 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,82 +1,82 @@
-/*
- * 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;
-
-/**
- * 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).
- *
- * @author Costin Leau
- * @since 3.1
- */
-public interface Cache {
-
- /**
- * Return the cache name.
- */
- String getName();
-
- /**
- * Return the the underlying native cache provider.
- */
- Object getNativeCache();
-
- /**
- * 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
- */
- ValueWrapper get(Object key);
-
- /**
- * 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 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);
-
- /**
- * 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);
-
- /**
- * Remove all mappings from the cache.
- */
- void clear();
-
-
- /**
- * A (wrapper) object representing a cache value.
- */
- interface ValueWrapper {
-
- /**
- * Return the actual value in the cache.
- */
- Object get();
- }
-
-}
+/*
+ * 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;
+
+/**
+ * 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 {@code null}).
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+public interface Cache {
+
+ /**
+ * Return the cache name.
+ */
+ String getName();
+
+ /**
+ * Return the the underlying native cache provider.
+ */
+ Object getNativeCache();
+
+ /**
+ * 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
+ */
+ ValueWrapper get(Object key);
+
+ /**
+ * 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 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);
+
+ /**
+ * 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);
+
+ /**
+ * Remove all mappings from the cache.
+ */
+ void clear();
+
+
+ /**
+ * A (wrapper) object representing a cache value.
+ */
+ interface ValueWrapper {
+
+ /**
+ * Return the actual value in the cache.
+ */
+ Object get();
+ }
+
+}
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 186f188cdf7..86228014eac 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,42 +1,42 @@
-/*
- * 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;
-
-import java.util.Collection;
-
-/**
- * A manager for a set of {@link Cache}s.
- *
- * @author Costin Leau
- * @since 3.1
- */
-public interface CacheManager {
-
- /**
- * 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);
-
- /**
- * Return a collection of the caches known by this cache manager.
- * @return names of caches known by the cache manager.
- */
- Collection getCacheNames();
-
-}
+/*
+ * 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;
+
+import java.util.Collection;
+
+/**
+ * A manager for a set of {@link Cache}s.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+public interface CacheManager {
+
+ /**
+ * Return the cache associated with the given name.
+ * @param name cache identifier (must not be {@code null})
+ * @return associated cache, or {@code null} if none is found
+ */
+ Cache getCache(String name);
+
+ /**
+ * 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 9aab40515bf..023a158d0cf 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,130 +1,130 @@
-/*
- * 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 java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource;
-import org.springframework.cache.interceptor.CacheOperation;
-import org.springframework.util.Assert;
-
-/**
- *
- * Implementation of the {@link org.springframework.cache.interceptor.CacheOperationSource}
- * interface for working with caching metadata in JDK 1.5+ annotation format.
- *
- * This class reads Spring's JDK 1.5+ {@link Cacheable}, {@link CachePut} and {@link CacheEvict}
- * annotations and exposes corresponding caching operation definition to Spring's cache infrastructure.
- * This class may also serve as base class for a custom CacheOperationSource.
- *
- * @author Costin Leau
- * @since 3.1
- */
-@SuppressWarnings("serial")
-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.
- */
- public AnnotationCacheOperationSource() {
- this(true);
- }
-
- /**
- * 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)
- */
- public AnnotationCacheOperationSource(boolean publicMethodsOnly) {
- this.publicMethodsOnly = publicMethodsOnly;
- this.annotationParsers = new LinkedHashSet(1);
- this.annotationParsers.add(new SpringCacheAnnotationParser());
- }
-
- /**
- * Create a custom AnnotationCacheOperationSource.
- * @param annotationParsers the CacheAnnotationParser to use
- */
- public AnnotationCacheOperationSource(CacheAnnotationParser... annotationParsers) {
- this.publicMethodsOnly = true;
- Assert.notEmpty(annotationParsers, "At least one CacheAnnotationParser needs to be specified");
- Set parsers = new LinkedHashSet(annotationParsers.length);
- Collections.addAll(parsers, annotationParsers);
- this.annotationParsers = parsers;
- }
-
-
- @Override
- protected Collection findCacheOperations(Class> clazz) {
- return determineCacheOperations(clazz);
- }
-
- @Override
- protected Collection findCacheOperations(Method method) {
- return determineCacheOperations(method);
- }
-
- /**
- * Determine the cache operation definition for the given method or class.
- * This implementation delegates to configured
- * {@link CacheAnnotationParser CacheAnnotationParsers}
- * for parsing known annotations into Spring's metadata attribute class.
- * Returns null if it's not cacheable.
- *
Can be overridden to support custom annotations that carry caching metadata.
- * @param ae the annotated method or class
- * @return CacheOperation the configured caching operation,
- * or null if none was found
- */
- protected Collection determineCacheOperations(AnnotatedElement ae) {
- Collection ops = null;
-
- for (CacheAnnotationParser annotationParser : this.annotationParsers) {
- Collection annOps = annotationParser.parseCacheAnnotations(ae);
- if (annOps != null) {
- if (ops == null) {
- ops = new ArrayList();
- }
- ops.addAll(annOps);
- }
- }
- return ops;
- }
-
- /**
- * By default, only public methods can be made cacheable.
- */
- @Override
- protected boolean allowPublicMethodsOnly() {
- return this.publicMethodsOnly;
- }
-}
\ No newline at end of file
+/*
+ * 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 java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.springframework.cache.interceptor.AbstractFallbackCacheOperationSource;
+import org.springframework.cache.interceptor.CacheOperation;
+import org.springframework.util.Assert;
+
+/**
+ *
+ * Implementation of the {@link org.springframework.cache.interceptor.CacheOperationSource}
+ * interface for working with caching metadata in JDK 1.5+ annotation format.
+ *
+ * This class reads Spring's JDK 1.5+ {@link Cacheable}, {@link CachePut} and {@link CacheEvict}
+ * annotations and exposes corresponding caching operation definition to Spring's cache infrastructure.
+ * This class may also serve as base class for a custom CacheOperationSource.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+@SuppressWarnings("serial")
+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.
+ */
+ public AnnotationCacheOperationSource() {
+ this(true);
+ }
+
+ /**
+ * 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)
+ */
+ public AnnotationCacheOperationSource(boolean publicMethodsOnly) {
+ this.publicMethodsOnly = publicMethodsOnly;
+ this.annotationParsers = new LinkedHashSet(1);
+ this.annotationParsers.add(new SpringCacheAnnotationParser());
+ }
+
+ /**
+ * Create a custom AnnotationCacheOperationSource.
+ * @param annotationParsers the CacheAnnotationParser to use
+ */
+ public AnnotationCacheOperationSource(CacheAnnotationParser... annotationParsers) {
+ this.publicMethodsOnly = true;
+ Assert.notEmpty(annotationParsers, "At least one CacheAnnotationParser needs to be specified");
+ Set parsers = new LinkedHashSet(annotationParsers.length);
+ Collections.addAll(parsers, annotationParsers);
+ this.annotationParsers = parsers;
+ }
+
+
+ @Override
+ protected Collection findCacheOperations(Class> clazz) {
+ return determineCacheOperations(clazz);
+ }
+
+ @Override
+ protected Collection findCacheOperations(Method method) {
+ return determineCacheOperations(method);
+ }
+
+ /**
+ * Determine the cache operation definition for the given method or class.
+ * This implementation delegates to configured
+ * {@link CacheAnnotationParser CacheAnnotationParsers}
+ * for parsing known annotations into Spring's metadata attribute class.
+ * Returns null if it's not cacheable.
+ *
Can be overridden to support custom annotations that carry caching metadata.
+ * @param ae the annotated method or class
+ * @return CacheOperation the configured caching operation,
+ * or null if none was found
+ */
+ protected Collection determineCacheOperations(AnnotatedElement ae) {
+ Collection ops = null;
+
+ for (CacheAnnotationParser annotationParser : this.annotationParsers) {
+ Collection annOps = annotationParser.parseCacheAnnotations(ae);
+ if (annOps != null) {
+ if (ops == null) {
+ ops = new ArrayList();
+ }
+ ops.addAll(annOps);
+ }
+ }
+ return ops;
+ }
+
+ /**
+ * By default, only public methods can be made cacheable.
+ */
+ @Override
+ protected boolean allowPublicMethodsOnly() {
+ return this.publicMethodsOnly;
+ }
+}
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 d5a54abe9d9..fd86d800360 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,48 +1,47 @@
-/*
- * 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.lang.reflect.AnnotatedElement;
-import java.util.Collection;
-
-import org.springframework.cache.interceptor.CacheOperation;
-
-
-/**
- * Strategy interface for parsing known caching annotation types.
- * {@link AnnotationCacheDefinitionSource} delegates to such
- * parsers for supporting specific annotation types such as Spring's own
- * {@link Cacheable}, {@link CachePut} or {@link CacheEvict}.
- *
- * @author Costin Leau
- * @since 3.1
- */
-public interface CacheAnnotationParser {
-
- /**
- * Parses the cache definition for the given method or class,
- * based on a known annotation type.
- * This essentially parses a known cache annotation into Spring's
- * metadata attribute class. Returns null if the method/class
- * is not cacheable.
- * @param ae the annotated method or class
- * @return CacheOperation the configured caching operation,
- * or null if none was found
- * @see AnnotationCacheOperationSource#determineCacheOperation
- */
- Collection parseCacheAnnotations(AnnotatedElement ae);
-}
+/*
+ * 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.lang.reflect.AnnotatedElement;
+import java.util.Collection;
+
+import org.springframework.cache.interceptor.CacheOperation;
+
+/**
+ * Strategy interface for parsing known caching annotation types.
+ * {@link AnnotationCacheDefinitionSource} delegates to such
+ * parsers for supporting specific annotation types such as Spring's own
+ * {@link Cacheable}, {@link CachePut} or {@link CacheEvict}.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+public interface CacheAnnotationParser {
+
+ /**
+ * Parses the cache definition for the given method or class,
+ * based on a known annotation type.
+ * This essentially parses a known cache annotation into Spring's
+ * metadata attribute class. Returns {@code null} if the method/class
+ * is not cacheable.
+ * @param ae the annotated method or class
+ * @return CacheOperation the configured caching operation,
+ * or {@code null} if none was found
+ * @see AnnotationCacheOperationSource#determineCacheOperation
+ */
+ Collection parseCacheAnnotations(AnnotatedElement ae);
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheDefinitions.java b/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheDefinitions.java
index 0aa4947f83b..8807a5cc4b1 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheDefinitions.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/annotation/CacheDefinitions.java
@@ -1,43 +1,44 @@
-/*
- * Copyright 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.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Group annotation for multiple cache annotations (of different or the same type).
- *
- * @author Costin Leau
- * @since 3.1
- */
-@Target({ ElementType.METHOD, ElementType.TYPE })
-@Retention(RetentionPolicy.RUNTIME)
-@Inherited
-@Documented
-public @interface CacheDefinitions {
-
- Cacheable[] cacheable() default {};
-
- CachePut[] put() default {};
-
- CacheEvict[] evict() default {};
-}
+/*
+ * 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.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Group annotation for multiple cache annotations (of different or the same type).
+ *
+ * @author Costin Leau
+ * @author Chris Beams
+ * @since 3.1
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface CacheDefinitions {
+
+ Cacheable[] cacheable() default {};
+
+ CachePut[] put() default {};
+
+ CacheEvict[] evict() default {};
+}
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 6414d17efd8..a96f8f8f65e 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,66 +1,66 @@
-/*
- * 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.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-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})
-@Retention(RetentionPolicy.RUNTIME)
-@Inherited
-@Documented
-public @interface CacheEvict {
-
- /**
- * Qualifier value for the specified cached operation.
- * May be used to determine the target cache (or caches), matching the qualifier
- * value (or the bean name(s)) of (a) specific bean definition.
- */
- String[] value();
-
- /**
- * Spring Expression Language (SpEL) attribute for computing the key dynamically.
- *
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.
- */
- 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
- * {@link CacheKey key} is not allowed.
- */
- boolean allEntries() default false;
-
-}
+/*
+ * 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.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+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})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface CacheEvict {
+
+ /**
+ * Qualifier value for the specified cached operation.
+ *
May be used to determine the target cache (or caches), matching the qualifier
+ * value (or the bean name(s)) of (a) specific bean definition.
+ */
+ String[] value();
+
+ /**
+ * Spring Expression Language (SpEL) attribute for computing the key dynamically.
+ *
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.
+ */
+ 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
+ * {@link CacheKey key} is not allowed.
+ */
+ boolean allEntries() default false;
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/annotation/CachePut.java b/org.springframework.context/src/main/java/org/springframework/cache/annotation/CachePut.java
index dbeb6aeef6f..0cc7f883f19 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/annotation/CachePut.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/annotation/CachePut.java
@@ -1,62 +1,61 @@
-/*
- * Copyright 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.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.springframework.cache.Cache;
-
-/**
- *
- * Annotation indicating that a method (or all methods on a class) trigger(s)
- * a {@link Cache#put(Object, Object)} operation. As opposed to {@link Cacheable} annotation,
- * this annotation does not cause the target method to be skipped - rather it
- * always causes the method to be invoked and its result to be placed into the cache.
- *
- * @author Costin Leau
- * @since 3.1
- */
-@Target({ ElementType.METHOD, ElementType.TYPE })
-@Retention(RetentionPolicy.RUNTIME)
-@Inherited
-@Documented
-public @interface CachePut {
-
- /**
- * Name of the caches in which the update takes place.
- *
May be used to determine the target cache (or caches), matching the
- * qualifier value (or the bean name(s)) of (a) specific bean definition.
- */
- String[] value();
-
- /**
- * Spring Expression Language (SpEL) attribute for computing the key dynamically.
- *
Default is "", meaning all method parameters are considered as a key.
- */
- String key() default "";
-
- /**
- * Spring Expression Language (SpEL) attribute used for conditioning the cache update.
- *
Default is "", meaning the method result is always cached.
- */
- String condition() default "";
-}
+/*
+ * Copyright 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.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.springframework.cache.Cache;
+
+/**
+ * Annotation indicating that a method (or all methods on a class) trigger(s)
+ * a {@link Cache#put(Object, Object)} operation. As opposed to {@link Cacheable} annotation,
+ * this annotation does not cause the target method to be skipped - rather it
+ * always causes the method to be invoked and its result to be placed into the cache.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+@Target({ ElementType.METHOD, ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface CachePut {
+
+ /**
+ * Name of the caches in which the update takes place.
+ *
May be used to determine the target cache (or caches), matching the
+ * qualifier value (or the bean name(s)) of (a) specific bean definition.
+ */
+ String[] value();
+
+ /**
+ * Spring Expression Language (SpEL) attribute for computing the key dynamically.
+ *
Default is "", meaning all method parameters are considered as a key.
+ */
+ String key() default "";
+
+ /**
+ * Spring Expression Language (SpEL) attribute used for conditioning the cache update.
+ *
Default is "", meaning the method result is always cached.
+ */
+ String condition() default "";
+}
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 c6a33e9a5d7..447ce62b4f8 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,59 +1,59 @@
-/*
- * 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.lang.annotation.Documented;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Inherited;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-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
- * returned instance is used as the cache value.
- *
- * @author Costin Leau
- * @since 3.1
- */
-@Target({ElementType.METHOD, ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-@Inherited
-@Documented
-public @interface Cacheable {
-
- /**
- * Name of the caches in which the update takes place.
- *
May be used to determine the target cache (or caches), matching the
- * qualifier value (or the bean name(s)) of (a) specific bean definition.
- */
- String[] value();
-
- /**
- * Spring Expression Language (SpEL) attribute for computing the key dynamically.
- *
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.
- */
- String condition() default "";
-}
+/*
+ * 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.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+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
+ * returned instance is used as the cache value.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+@Target({ElementType.METHOD, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+@Documented
+public @interface Cacheable {
+
+ /**
+ * Name of the caches in which the update takes place.
+ *
May be used to determine the target cache (or caches), matching the
+ * qualifier value (or the bean name(s)) of (a) specific bean definition.
+ */
+ String[] value();
+
+ /**
+ * Spring Expression Language (SpEL) attribute for computing the key dynamically.
+ *
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.
+ */
+ String condition() default "";
+}
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
index 4cffa9f6b28..95009ff1dab 100644
--- 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
@@ -1,126 +1,127 @@
-/*
- * 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 java.util.ArrayList;
-import java.util.Collection;
-
-import org.springframework.cache.interceptor.CacheEvictOperation;
-import org.springframework.cache.interceptor.CacheOperation;
-import org.springframework.cache.interceptor.CachePutOperation;
-import org.springframework.cache.interceptor.CacheableOperation;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.util.ObjectUtils;
-
-/**
- * Strategy implementation for parsing Spring's {@link Cacheable}, {@link CacheEvict} and {@link CachePut} annotations.
- *
- * @author Costin Leau
- * @author Juergen Hoeller
- * @since 3.1
- */
-@SuppressWarnings("serial")
-public class SpringCacheAnnotationParser implements CacheAnnotationParser, Serializable {
-
- public Collection parseCacheAnnotations(AnnotatedElement ae) {
- Collection ops = null;
-
- Cacheable cache = AnnotationUtils.getAnnotation(ae, Cacheable.class);
- if (cache != null) {
- ops = lazyInit(ops);
- ops.add(parseCacheableAnnotation(ae, cache));
- }
- CacheEvict evict = AnnotationUtils.getAnnotation(ae, CacheEvict.class);
- if (evict != null) {
- ops = lazyInit(ops);
- ops.add(parseEvictAnnotation(ae, evict));
- }
- CachePut update = AnnotationUtils.getAnnotation(ae, CachePut.class);
- if (update != null) {
- ops = lazyInit(ops);
- ops.add(parseUpdateAnnotation(ae, update));
- }
- CacheDefinitions definition = AnnotationUtils.getAnnotation(ae, CacheDefinitions.class);
- if (definition != null) {
- ops = lazyInit(ops);
- ops.addAll(parseDefinitionAnnotation(ae, definition));
- }
- return ops;
- }
-
- private Collection lazyInit(Collection ops) {
- return (ops != null ? ops : new ArrayList(2));
- }
-
- CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, Cacheable ann) {
- CacheableOperation cuo = new CacheableOperation();
- 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;
- }
-
- CacheOperation parseUpdateAnnotation(AnnotatedElement ae, CachePut ann) {
- CachePutOperation cuo = new CachePutOperation();
- cuo.setCacheNames(ann.value());
- cuo.setCondition(ann.condition());
- cuo.setKey(ann.key());
- cuo.setName(ae.toString());
- return cuo;
- }
-
- Collection parseDefinitionAnnotation(AnnotatedElement ae, CacheDefinitions ann) {
- Collection ops = null;
-
- Cacheable[] cacheables = ann.cacheable();
- if (!ObjectUtils.isEmpty(cacheables)) {
- ops = lazyInit(ops);
- for (Cacheable cacheable : cacheables) {
- ops.add(parseCacheableAnnotation(ae, cacheable));
- }
- }
- CacheEvict[] evicts = ann.evict();
- if (!ObjectUtils.isEmpty(evicts)) {
- ops = lazyInit(ops);
- for (CacheEvict evict : evicts) {
- ops.add(parseEvictAnnotation(ae, evict));
- }
- }
- CachePut[] updates = ann.put();
- if (!ObjectUtils.isEmpty(updates)) {
- ops = lazyInit(ops);
- for (CachePut update : updates) {
- ops.add(parseUpdateAnnotation(ae, update));
- }
- }
-
- return ops;
- }
-}
\ No newline at end of file
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collection;
+
+import org.springframework.cache.interceptor.CacheEvictOperation;
+import org.springframework.cache.interceptor.CacheOperation;
+import org.springframework.cache.interceptor.CachePutOperation;
+import org.springframework.cache.interceptor.CacheableOperation;
+import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.util.ObjectUtils;
+
+/**
+ * Strategy implementation for parsing Spring's {@link Cacheable},
+ * {@link CacheEvict} and {@link CachePut} annotations.
+ *
+ * @author Costin Leau
+ * @author Juergen Hoeller
+ * @since 3.1
+ */
+@SuppressWarnings("serial")
+public class SpringCacheAnnotationParser implements CacheAnnotationParser, Serializable {
+
+ public Collection parseCacheAnnotations(AnnotatedElement ae) {
+ Collection ops = null;
+
+ Cacheable cache = AnnotationUtils.getAnnotation(ae, Cacheable.class);
+ if (cache != null) {
+ ops = lazyInit(ops);
+ ops.add(parseCacheableAnnotation(ae, cache));
+ }
+ CacheEvict evict = AnnotationUtils.getAnnotation(ae, CacheEvict.class);
+ if (evict != null) {
+ ops = lazyInit(ops);
+ ops.add(parseEvictAnnotation(ae, evict));
+ }
+ CachePut update = AnnotationUtils.getAnnotation(ae, CachePut.class);
+ if (update != null) {
+ ops = lazyInit(ops);
+ ops.add(parseUpdateAnnotation(ae, update));
+ }
+ CacheDefinitions definition = AnnotationUtils.getAnnotation(ae, CacheDefinitions.class);
+ if (definition != null) {
+ ops = lazyInit(ops);
+ ops.addAll(parseDefinitionAnnotation(ae, definition));
+ }
+ return ops;
+ }
+
+ private Collection lazyInit(Collection ops) {
+ return (ops != null ? ops : new ArrayList(2));
+ }
+
+ CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, Cacheable ann) {
+ CacheableOperation cuo = new CacheableOperation();
+ 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;
+ }
+
+ CacheOperation parseUpdateAnnotation(AnnotatedElement ae, CachePut ann) {
+ CachePutOperation cuo = new CachePutOperation();
+ cuo.setCacheNames(ann.value());
+ cuo.setCondition(ann.condition());
+ cuo.setKey(ann.key());
+ cuo.setName(ae.toString());
+ return cuo;
+ }
+
+ Collection parseDefinitionAnnotation(AnnotatedElement ae, CacheDefinitions ann) {
+ Collection ops = null;
+
+ Cacheable[] cacheables = ann.cacheable();
+ if (!ObjectUtils.isEmpty(cacheables)) {
+ ops = lazyInit(ops);
+ for (Cacheable cacheable : cacheables) {
+ ops.add(parseCacheableAnnotation(ae, cacheable));
+ }
+ }
+ CacheEvict[] evicts = ann.evict();
+ if (!ObjectUtils.isEmpty(evicts)) {
+ ops = lazyInit(ops);
+ for (CacheEvict evict : evicts) {
+ ops.add(parseEvictAnnotation(ae, evict));
+ }
+ }
+ CachePut[] updates = ann.put();
+ if (!ObjectUtils.isEmpty(updates)) {
+ ops = lazyInit(ops);
+ for (CachePut update : updates) {
+ ops.add(parseUpdateAnnotation(ae, update));
+ }
+ }
+
+ return ops;
+ }
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/annotation/package-info.java b/org.springframework.context/src/main/java/org/springframework/cache/annotation/package-info.java
index e9d9a11f3bd..6c230a8eaa5 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/annotation/package-info.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/annotation/package-info.java
@@ -1,9 +1,8 @@
-
-/**
- * JDK 1.5+ annotation for caching demarcation.
- * Hooked into Spring's caching interception infrastructure
- * via CacheOperationSource implementation.
- *
- */
-package org.springframework.cache.annotation;
-
+
+/**
+ * Annotations and supporting classes for declarative cache management.
+ * Hooked into Spring's caching interception infrastructure
+ * via {@link org.springframework.cache.interceptor.CacheOperationSource
+ * CacheOperationSource} implementation.
+ */
+package org.springframework.cache.annotation;
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 945f920ef63..0fa632d2a0f 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,145 +1,145 @@
-/*
- * 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.io.Serializable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
-import org.springframework.cache.Cache;
-import org.springframework.cache.support.ValueWrapperImpl;
-
-/**
- * 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.
- *
- * @author Costin Leau
- * @author Juergen Hoeller
- * @since 3.1
- */
-public class ConcurrentMapCache implements Cache {
-
- private static final Object NULL_HOLDER = new NullHolder();
-
- private final String name;
-
- private final ConcurrentMap store;
-
- private final boolean allowNullValues;
-
-
- /**
- * Create a new ConcurrentMapCache with the specified name.
- * @param name the name of the cache
- */
- public ConcurrentMapCache(String name) {
- 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);
- }
-
- /**
- * 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 this.name;
- }
-
- public ConcurrentMap getNativeCache() {
- return this.store;
- }
-
- public boolean isAllowNullValues() {
- return this.allowNullValues;
- }
-
- public ValueWrapper get(Object key) {
- Object value = this.store.get(key);
- return (value != null ? new ValueWrapperImpl(fromStoreValue(value)) : null);
- }
-
- public void put(Object key, Object value) {
- this.store.put(key, toStoreValue(value));
- }
-
- public void evict(Object key) {
- this.store.remove(key);
- }
-
- 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 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;
- }
-
-
- private static class NullHolder implements Serializable {
- }
-
-}
+/*
+ * 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.io.Serializable;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.springframework.cache.Cache;
+import org.springframework.cache.support.ValueWrapperImpl;
+
+/**
+ * Simple {@link Cache} implementation based on the core JDK
+ * {@code 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 {@code 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.
+ *
+ * @author Costin Leau
+ * @author Juergen Hoeller
+ * @since 3.1
+ */
+public class ConcurrentMapCache implements Cache {
+
+ private static final Object NULL_HOLDER = new NullHolder();
+
+ private final String name;
+
+ private final ConcurrentMap store;
+
+ private final boolean allowNullValues;
+
+
+ /**
+ * Create a new ConcurrentMapCache with the specified name.
+ * @param name the name of the cache
+ */
+ public ConcurrentMapCache(String name) {
+ 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);
+ }
+
+ /**
+ * 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 this.name;
+ }
+
+ public ConcurrentMap getNativeCache() {
+ return this.store;
+ }
+
+ public boolean isAllowNullValues() {
+ return this.allowNullValues;
+ }
+
+ public ValueWrapper get(Object key) {
+ Object value = this.store.get(key);
+ return (value != null ? new ValueWrapperImpl(fromStoreValue(value)) : null);
+ }
+
+ public void put(Object key, Object value) {
+ this.store.put(key, toStoreValue(value));
+ }
+
+ public void evict(Object key) {
+ this.store.remove(key);
+ }
+
+ 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 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;
+ }
+
+
+ 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 c7a9474ecdd..26b242310b9 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,101 +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.concurrent.ConcurrentMap;
-
-import org.springframework.beans.factory.BeanNameAware;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.util.StringUtils;
-
-/**
- * {@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 {
-
- private String name = "";
-
- private ConcurrentMap store;
-
- private boolean allowNullValues = true;
-
- private ConcurrentMapCache cache;
-
-
- /**
- * Specify the name of the cache.
- * Default is "" (empty String).
- */
- public void setName(String name) {
- this.name = name;
- }
-
- /**
- * 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;
- }
-
- /**
- * 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.hasLength(this.name)) {
- setName(beanName);
- }
- }
-
- public void afterPropertiesSet() {
- this.cache = (this.store != null ? new ConcurrentMapCache(this.name, this.store, this.allowNullValues) :
- new ConcurrentMapCache(this.name, this.allowNullValues));
- }
-
-
- public ConcurrentMapCache getObject() {
- return this.cache;
- }
-
- public Class> getObjectType() {
- return ConcurrentMapCache.class;
- }
-
- public boolean isSingleton() {
- return true;
- }
-
-}
+/*
+ * 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.concurrent.ConcurrentMap;
+
+import org.springframework.beans.factory.BeanNameAware;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.StringUtils;
+
+/**
+ * {@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 {
+
+ private String name = "";
+
+ private ConcurrentMap store;
+
+ private boolean allowNullValues = true;
+
+ private ConcurrentMapCache cache;
+
+
+ /**
+ * Specify the name of the cache.
+ * Default is "" (empty String).
+ */
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ /**
+ * 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;
+ }
+
+ /**
+ * Set whether to allow {@code 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.hasLength(this.name)) {
+ setName(beanName);
+ }
+ }
+
+ public void afterPropertiesSet() {
+ this.cache = (this.store != null ? new ConcurrentMapCache(this.name, this.store, this.allowNullValues) :
+ new ConcurrentMapCache(this.name, this.allowNullValues));
+ }
+
+
+ public ConcurrentMapCache getObject() {
+ return this.cache;
+ }
+
+ 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
index 2d447e6d822..fd59da23c8a 100644
--- 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
@@ -1,101 +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);
- }
-
-}
+/*
+ * 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/concurrent/package-info.java b/org.springframework.context/src/main/java/org/springframework/cache/concurrent/package-info.java
index 4965e8534d0..c322897233a 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/concurrent/package-info.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/concurrent/package-info.java
@@ -1,10 +1,9 @@
-
-/**
- *
- * Implementation package for java.util.concurrent based
- * caches. Provides a CacheManager and Cache implementation
- * for usage in a Spring context.
- *
- */
-package org.springframework.cache.concurrent;
-
+
+/**
+ * Implementation package for {@code java.util.concurrent} based caches.
+ * Provides a {@link org.springframework.cache.CacheManager CacheManager}
+ * and {@link org.springframework.cache.Cache Cache} implementation for
+ * use in a Spring context.
+ */
+package org.springframework.cache.concurrent;
+
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 525b317f3c0..26a736dd41e 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,142 +1,143 @@
-/*
- * 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.config;
-
-import static org.springframework.context.annotation.AnnotationConfigUtils.*;
-
-import org.springframework.aop.config.AopNamespaceUtils;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.parsing.BeanComponentDefinition;
-import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.beans.factory.xml.BeanDefinitionParser;
-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;
-
-/**
- * {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
- * implementation that allows users to easily configure all the infrastructure
- * beans required to enable annotation-driven cache demarcation.
- *
- * By default, all proxies are created as JDK proxies. This may cause some
- * problems if you are injecting objects as concrete classes rather than
- * interfaces. To overcome this restriction you can set the
- * 'proxy-target-class' attribute to 'true', which
- * will result in class-based proxies being created.
- *
- * @author Costin Leau
- * @since 3.1
- */
-class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser {
-
- /**
- * Parses the '<cache:annotation-driven/>' tag. Will
- * {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary register an AutoProxyCreator}
- * with the container as necessary.
- */
- public BeanDefinition parse(Element element, ParserContext parserContext) {
- String mode = element.getAttribute("mode");
- if ("aspectj".equals(mode)) {
- // mode="aspectj"
- registerCacheAspect(element, parserContext);
- }
- else {
- // mode="proxy"
- AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
- }
-
- return null;
- }
-
- private static void parseCacheManagerProperty(Element element, BeanDefinition def) {
- def.getPropertyValues().add("cacheManager",
- new RuntimeBeanReference(CacheNamespaceHandler.extractCacheManager(element)));
- }
-
- /**
- * Registers a
- *
- *
- *
- *
- *
- *
- * @param element
- * @param parserContext
- */
- private void registerCacheAspect(Element element, ParserContext parserContext) {
- if (!parserContext.getRegistry().containsBeanDefinition(CACHE_ASPECT_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition();
- def.setBeanClassName(CACHE_ASPECT_CLASS_NAME);
- def.setFactoryMethodName("aspectOf");
- parseCacheManagerProperty(element, def);
- parserContext.registerBeanComponent(new BeanComponentDefinition(def, CACHE_ASPECT_BEAN_NAME));
- }
- }
-
-
- /**
- * Inner class to just introduce an AOP framework dependency when actually in proxy mode.
- */
- private static class AopAutoProxyConfigurer {
-
- public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
- AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
-
- if (!parserContext.getRegistry().containsBeanDefinition(CACHE_ADVISOR_BEAN_NAME)) {
- Object eleSource = parserContext.extractSource(element);
-
- // Create the CacheOperationSource definition.
- RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationCacheOperationSource.class);
- sourceDef.setSource(eleSource);
- sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
-
- // Create the CacheInterceptor definition.
- RootBeanDefinition interceptorDef = new RootBeanDefinition(CacheInterceptor.class);
- interceptorDef.setSource(eleSource);
- interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- parseCacheManagerProperty(element, interceptorDef);
- CacheNamespaceHandler.parseKeyGenerator(element, interceptorDef);
- interceptorDef.getPropertyValues().add("cacheOperationSources", 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("cacheOperationSource", new RuntimeBeanReference(sourceName));
- advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
- if (element.hasAttribute("order")) {
- advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
- }
- parserContext.getRegistry().registerBeanDefinition(CACHE_ADVISOR_BEAN_NAME, advisorDef);
-
- CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(),
- eleSource);
- compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
- compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
- compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, CACHE_ADVISOR_BEAN_NAME));
- parserContext.registerComponent(compositeDef);
- }
- }
- }
-}
\ No newline at end of file
+/*
+ * 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.config;
+
+import static org.springframework.context.annotation.AnnotationConfigUtils.*;
+
+import org.springframework.aop.config.AopNamespaceUtils;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.parsing.BeanComponentDefinition;
+import org.springframework.beans.factory.parsing.CompositeComponentDefinition;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.BeanDefinitionParser;
+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;
+
+/**
+ * {@link org.springframework.beans.factory.xml.BeanDefinitionParser}
+ * implementation that allows users to easily configure all the
+ * infrastructure beans required to enable annotation-driven cache
+ * demarcation.
+ *
+ * By default, all proxies are created as JDK proxies. This may cause
+ * some problems if you are injecting objects as concrete classes rather
+ * than interfaces. To overcome this restriction you can set the
+ * '{@code proxy-target-class}' attribute to '{@code true}', which will
+ * result in class-based proxies being created.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser {
+
+ /**
+ * Parses the '{@code }' tag. Will
+ * {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary
+ * register an AutoProxyCreator} with the container as necessary.
+ */
+ public BeanDefinition parse(Element element, ParserContext parserContext) {
+ String mode = element.getAttribute("mode");
+ if ("aspectj".equals(mode)) {
+ // mode="aspectj"
+ registerCacheAspect(element, parserContext);
+ }
+ else {
+ // mode="proxy"
+ AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
+ }
+
+ return null;
+ }
+
+ private static void parseCacheManagerProperty(Element element, BeanDefinition def) {
+ def.getPropertyValues().add("cacheManager",
+ new RuntimeBeanReference(CacheNamespaceHandler.extractCacheManager(element)));
+ }
+
+ /**
+ * Registers a
+ *
+ *
+ *
+ *
+ *
+ *
+ * @param element
+ * @param parserContext
+ */
+ private void registerCacheAspect(Element element, ParserContext parserContext) {
+ if (!parserContext.getRegistry().containsBeanDefinition(CACHE_ASPECT_BEAN_NAME)) {
+ RootBeanDefinition def = new RootBeanDefinition();
+ def.setBeanClassName(CACHE_ASPECT_CLASS_NAME);
+ def.setFactoryMethodName("aspectOf");
+ parseCacheManagerProperty(element, def);
+ parserContext.registerBeanComponent(new BeanComponentDefinition(def, CACHE_ASPECT_BEAN_NAME));
+ }
+ }
+
+
+ /**
+ * Inner class to just introduce an AOP framework dependency when actually in proxy mode.
+ */
+ private static class AopAutoProxyConfigurer {
+
+ public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
+ AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
+
+ if (!parserContext.getRegistry().containsBeanDefinition(CACHE_ADVISOR_BEAN_NAME)) {
+ Object eleSource = parserContext.extractSource(element);
+
+ // Create the CacheOperationSource definition.
+ RootBeanDefinition sourceDef = new RootBeanDefinition(AnnotationCacheOperationSource.class);
+ sourceDef.setSource(eleSource);
+ sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
+
+ // Create the CacheInterceptor definition.
+ RootBeanDefinition interceptorDef = new RootBeanDefinition(CacheInterceptor.class);
+ interceptorDef.setSource(eleSource);
+ interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
+ parseCacheManagerProperty(element, interceptorDef);
+ CacheNamespaceHandler.parseKeyGenerator(element, interceptorDef);
+ interceptorDef.getPropertyValues().add("cacheOperationSources", 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("cacheOperationSource", new RuntimeBeanReference(sourceName));
+ advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
+ if (element.hasAttribute("order")) {
+ advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
+ }
+ parserContext.getRegistry().registerBeanDefinition(CACHE_ADVISOR_BEAN_NAME, advisorDef);
+
+ CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(),
+ eleSource);
+ compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
+ compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
+ compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, CACHE_ADVISOR_BEAN_NAME));
+ parserContext.registerComponent(compositeDef);
+ }
+ }
+ }
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/config/CacheAdviceParser.java b/org.springframework.context/src/main/java/org/springframework/cache/config/CacheAdviceParser.java
index 5150169cc19..1b033832096 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/config/CacheAdviceParser.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/config/CacheAdviceParser.java
@@ -1,216 +1,215 @@
-/*
- * Copyright 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.config;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import org.springframework.beans.factory.config.TypedStringValue;
-import org.springframework.beans.factory.parsing.ReaderContext;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.ManagedList;
-import org.springframework.beans.factory.support.ManagedMap;
-import org.springframework.beans.factory.support.RootBeanDefinition;
-import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
-import org.springframework.beans.factory.xml.ParserContext;
-import org.springframework.cache.annotation.AnnotationCacheOperationSource;
-import org.springframework.cache.interceptor.CacheEvictOperation;
-import org.springframework.cache.interceptor.CacheInterceptor;
-import org.springframework.cache.interceptor.CacheOperation;
-import org.springframework.cache.interceptor.CachePutOperation;
-import org.springframework.cache.interceptor.CacheableOperation;
-import org.springframework.cache.interceptor.NameMatchCacheOperationSource;
-import org.springframework.util.StringUtils;
-import org.springframework.util.xml.DomUtils;
-import org.w3c.dom.Element;
-
-/**
- * {@link org.springframework.beans.factory.xml.BeanDefinitionParser
- * BeanDefinitionParser} for the {@code } tag.
- *
- * @author Costin Leau
- *
- */
-class CacheAdviceParser extends AbstractSingleBeanDefinitionParser {
-
- /**
- * Simple, reusable class used for overriding defaults.
- *
- * @author Costin Leau
- */
- private static class Props {
-
- private String key, condition, method;
- private String[] caches = null;
-
- Props(Element root) {
- String defaultCache = root.getAttribute("cache");
- key = root.getAttribute("key");
- condition = root.getAttribute("condition");
- method = root.getAttribute(METHOD_ATTRIBUTE);
-
- if (StringUtils.hasText(defaultCache)) {
- caches = StringUtils.commaDelimitedListToStringArray(defaultCache.trim());
- }
- }
-
- CacheOperation merge(Element element, ReaderContext readerCtx, CacheOperation op) {
- String cache = element.getAttribute("cache");
- String k = element.getAttribute("key");
- String c = element.getAttribute("condition");
-
- String[] localCaches = caches;
- String localKey = key, localCondition = condition;
-
- // sanity check
- if (StringUtils.hasText(cache)) {
- localCaches = StringUtils.commaDelimitedListToStringArray(cache.trim());
- } else {
- if (caches == null) {
- readerCtx.error("No cache specified specified for " + element.getNodeName(), element);
- }
- }
-
- if (StringUtils.hasText(k)) {
- localKey = k.trim();
- }
-
- if (StringUtils.hasText(c)) {
- localCondition = c.trim();
- }
- op.setCacheNames(localCaches);
- op.setKey(localKey);
- op.setCondition(localCondition);
-
- return op;
- }
-
- String merge(Element element, ReaderContext readerCtx) {
- String m = element.getAttribute(METHOD_ATTRIBUTE);
-
- if (StringUtils.hasText(m)) {
- return m.trim();
- }
- if (StringUtils.hasText(method)) {
- return method;
- }
- readerCtx.error("No method specified for " + element.getNodeName(), element);
- return null;
- }
- }
-
- private static final String CACHEABLE_ELEMENT = "cacheable";
- private static final String CACHE_EVICT_ELEMENT = "cache-evict";
- private static final String CACHE_PUT_ELEMENT = "cache-put";
- private static final String METHOD_ATTRIBUTE = "method";
- private static final String DEFS_ELEMENT = "definitions";
-
- @Override
- protected Class> getBeanClass(Element element) {
- return CacheInterceptor.class;
- }
-
- @Override
- protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
- builder.addPropertyReference("cacheManager", CacheNamespaceHandler.extractCacheManager(element));
- CacheNamespaceHandler.parseKeyGenerator(element, builder.getBeanDefinition());
-
- List cacheDefs = DomUtils.getChildElementsByTagName(element, DEFS_ELEMENT);
- if (cacheDefs.size() >= 1) {
- // Using attributes source.
- List attributeSourceDefinitions = parseDefinitionsSources(cacheDefs, parserContext);
- builder.addPropertyValue("cacheOperationSources", attributeSourceDefinitions);
- } else {
- // Assume annotations source.
- builder.addPropertyValue("cacheOperationSources", new RootBeanDefinition(
- AnnotationCacheOperationSource.class));
- }
- }
-
- private List parseDefinitionsSources(List definitions, ParserContext parserContext) {
- ManagedList defs = new ManagedList(definitions.size());
-
- // extract default param for the definition
- for (Element element : definitions) {
- defs.add(parseDefinitionSource(element, parserContext));
- }
-
- return defs;
- }
-
- private RootBeanDefinition parseDefinitionSource(Element definition, ParserContext parserContext) {
- Props prop = new Props(definition);
- // add cacheable first
-
- ManagedMap> cacheOpMap = new ManagedMap>();
- cacheOpMap.setSource(parserContext.extractSource(definition));
-
- List cacheableCacheMethods = DomUtils.getChildElementsByTagName(definition, CACHEABLE_ELEMENT);
-
- for (Element opElement : cacheableCacheMethods) {
- String name = prop.merge(opElement, parserContext.getReaderContext());
- TypedStringValue nameHolder = new TypedStringValue(name);
- nameHolder.setSource(parserContext.extractSource(opElement));
- CacheOperation op = prop.merge(opElement, parserContext.getReaderContext(), new CacheableOperation());
-
- Collection col = cacheOpMap.get(nameHolder);
- if (col == null) {
- col = new ArrayList(2);
- cacheOpMap.put(nameHolder, col);
- }
- col.add(op);
- }
-
- List evictCacheMethods = DomUtils.getChildElementsByTagName(definition, CACHE_EVICT_ELEMENT);
-
- for (Element opElement : evictCacheMethods) {
- String name = prop.merge(opElement, parserContext.getReaderContext());
- TypedStringValue nameHolder = new TypedStringValue(name);
- nameHolder.setSource(parserContext.extractSource(opElement));
- CacheOperation op = prop.merge(opElement, parserContext.getReaderContext(), new CacheEvictOperation());
-
- Collection col = cacheOpMap.get(nameHolder);
- if (col == null) {
- col = new ArrayList(2);
- cacheOpMap.put(nameHolder, col);
- }
- col.add(op);
- }
-
- List putCacheMethods = DomUtils.getChildElementsByTagName(definition, CACHE_PUT_ELEMENT);
-
- for (Element opElement : putCacheMethods) {
- String name = prop.merge(opElement, parserContext.getReaderContext());
- TypedStringValue nameHolder = new TypedStringValue(name);
- nameHolder.setSource(parserContext.extractSource(opElement));
- CacheOperation op = prop.merge(opElement, parserContext.getReaderContext(), new CachePutOperation());
-
- Collection col = cacheOpMap.get(nameHolder);
- if (col == null) {
- col = new ArrayList(2);
- cacheOpMap.put(nameHolder, col);
- }
- col.add(op);
- }
-
- RootBeanDefinition attributeSourceDefinition = new RootBeanDefinition(NameMatchCacheOperationSource.class);
- attributeSourceDefinition.setSource(parserContext.extractSource(definition));
- attributeSourceDefinition.getPropertyValues().add("nameMap", cacheOpMap);
- return attributeSourceDefinition;
- }
-}
\ No newline at end of file
+/*
+ * Copyright 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.config;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.springframework.beans.factory.config.TypedStringValue;
+import org.springframework.beans.factory.parsing.ReaderContext;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.support.ManagedMap;
+import org.springframework.beans.factory.support.RootBeanDefinition;
+import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.cache.annotation.AnnotationCacheOperationSource;
+import org.springframework.cache.interceptor.CacheEvictOperation;
+import org.springframework.cache.interceptor.CacheInterceptor;
+import org.springframework.cache.interceptor.CacheOperation;
+import org.springframework.cache.interceptor.CachePutOperation;
+import org.springframework.cache.interceptor.CacheableOperation;
+import org.springframework.cache.interceptor.NameMatchCacheOperationSource;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Element;
+
+/**
+ * {@link org.springframework.beans.factory.xml.BeanDefinitionParser
+ * BeanDefinitionParser} for the {@code } tag.
+ *
+ * @author Costin Leau
+ */
+class CacheAdviceParser extends AbstractSingleBeanDefinitionParser {
+
+ /**
+ * Simple, reusable class used for overriding defaults.
+ *
+ * @author Costin Leau
+ */
+ private static class Props {
+
+ private String key, condition, method;
+ private String[] caches = null;
+
+ Props(Element root) {
+ String defaultCache = root.getAttribute("cache");
+ key = root.getAttribute("key");
+ condition = root.getAttribute("condition");
+ method = root.getAttribute(METHOD_ATTRIBUTE);
+
+ if (StringUtils.hasText(defaultCache)) {
+ caches = StringUtils.commaDelimitedListToStringArray(defaultCache.trim());
+ }
+ }
+
+ CacheOperation merge(Element element, ReaderContext readerCtx, CacheOperation op) {
+ String cache = element.getAttribute("cache");
+ String k = element.getAttribute("key");
+ String c = element.getAttribute("condition");
+
+ String[] localCaches = caches;
+ String localKey = key, localCondition = condition;
+
+ // sanity check
+ if (StringUtils.hasText(cache)) {
+ localCaches = StringUtils.commaDelimitedListToStringArray(cache.trim());
+ } else {
+ if (caches == null) {
+ readerCtx.error("No cache specified specified for " + element.getNodeName(), element);
+ }
+ }
+
+ if (StringUtils.hasText(k)) {
+ localKey = k.trim();
+ }
+
+ if (StringUtils.hasText(c)) {
+ localCondition = c.trim();
+ }
+ op.setCacheNames(localCaches);
+ op.setKey(localKey);
+ op.setCondition(localCondition);
+
+ return op;
+ }
+
+ String merge(Element element, ReaderContext readerCtx) {
+ String m = element.getAttribute(METHOD_ATTRIBUTE);
+
+ if (StringUtils.hasText(m)) {
+ return m.trim();
+ }
+ if (StringUtils.hasText(method)) {
+ return method;
+ }
+ readerCtx.error("No method specified for " + element.getNodeName(), element);
+ return null;
+ }
+ }
+
+ private static final String CACHEABLE_ELEMENT = "cacheable";
+ private static final String CACHE_EVICT_ELEMENT = "cache-evict";
+ private static final String CACHE_PUT_ELEMENT = "cache-put";
+ private static final String METHOD_ATTRIBUTE = "method";
+ private static final String DEFS_ELEMENT = "definitions";
+
+ @Override
+ protected Class> getBeanClass(Element element) {
+ return CacheInterceptor.class;
+ }
+
+ @Override
+ protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
+ builder.addPropertyReference("cacheManager", CacheNamespaceHandler.extractCacheManager(element));
+ CacheNamespaceHandler.parseKeyGenerator(element, builder.getBeanDefinition());
+
+ List cacheDefs = DomUtils.getChildElementsByTagName(element, DEFS_ELEMENT);
+ if (cacheDefs.size() >= 1) {
+ // Using attributes source.
+ List attributeSourceDefinitions = parseDefinitionsSources(cacheDefs, parserContext);
+ builder.addPropertyValue("cacheOperationSources", attributeSourceDefinitions);
+ } else {
+ // Assume annotations source.
+ builder.addPropertyValue("cacheOperationSources", new RootBeanDefinition(
+ AnnotationCacheOperationSource.class));
+ }
+ }
+
+ private List parseDefinitionsSources(List definitions, ParserContext parserContext) {
+ ManagedList defs = new ManagedList(definitions.size());
+
+ // extract default param for the definition
+ for (Element element : definitions) {
+ defs.add(parseDefinitionSource(element, parserContext));
+ }
+
+ return defs;
+ }
+
+ private RootBeanDefinition parseDefinitionSource(Element definition, ParserContext parserContext) {
+ Props prop = new Props(definition);
+ // add cacheable first
+
+ ManagedMap> cacheOpMap = new ManagedMap>();
+ cacheOpMap.setSource(parserContext.extractSource(definition));
+
+ List cacheableCacheMethods = DomUtils.getChildElementsByTagName(definition, CACHEABLE_ELEMENT);
+
+ for (Element opElement : cacheableCacheMethods) {
+ String name = prop.merge(opElement, parserContext.getReaderContext());
+ TypedStringValue nameHolder = new TypedStringValue(name);
+ nameHolder.setSource(parserContext.extractSource(opElement));
+ CacheOperation op = prop.merge(opElement, parserContext.getReaderContext(), new CacheableOperation());
+
+ Collection col = cacheOpMap.get(nameHolder);
+ if (col == null) {
+ col = new ArrayList(2);
+ cacheOpMap.put(nameHolder, col);
+ }
+ col.add(op);
+ }
+
+ List evictCacheMethods = DomUtils.getChildElementsByTagName(definition, CACHE_EVICT_ELEMENT);
+
+ for (Element opElement : evictCacheMethods) {
+ String name = prop.merge(opElement, parserContext.getReaderContext());
+ TypedStringValue nameHolder = new TypedStringValue(name);
+ nameHolder.setSource(parserContext.extractSource(opElement));
+ CacheOperation op = prop.merge(opElement, parserContext.getReaderContext(), new CacheEvictOperation());
+
+ Collection col = cacheOpMap.get(nameHolder);
+ if (col == null) {
+ col = new ArrayList(2);
+ cacheOpMap.put(nameHolder, col);
+ }
+ col.add(op);
+ }
+
+ List putCacheMethods = DomUtils.getChildElementsByTagName(definition, CACHE_PUT_ELEMENT);
+
+ for (Element opElement : putCacheMethods) {
+ String name = prop.merge(opElement, parserContext.getReaderContext());
+ TypedStringValue nameHolder = new TypedStringValue(name);
+ nameHolder.setSource(parserContext.extractSource(opElement));
+ CacheOperation op = prop.merge(opElement, parserContext.getReaderContext(), new CachePutOperation());
+
+ Collection col = cacheOpMap.get(nameHolder);
+ if (col == null) {
+ col = new ArrayList(2);
+ cacheOpMap.put(nameHolder, col);
+ }
+ col.add(op);
+ }
+
+ RootBeanDefinition attributeSourceDefinition = new RootBeanDefinition(NameMatchCacheOperationSource.class);
+ attributeSourceDefinition.setSource(parserContext.extractSource(definition));
+ attributeSourceDefinition.getPropertyValues().add("nameMap", cacheOpMap);
+ return attributeSourceDefinition;
+ }
+}
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 cf94fef85a2..40100245f35 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,58 +1,58 @@
-/*
- * 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.config;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.RuntimeBeanReference;
-import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
-import org.springframework.util.StringUtils;
-import org.w3c.dom.Element;
-
-/**
- * NamespaceHandler allowing for the configuration of
- * declarative cache management using either XML or using annotations.
- *
- * This namespace handler is the central piece of functionality in the
- * Spring cache management facilities.
- *
- * @author Costin Leau
- * @since 3.1
- */
-public class CacheNamespaceHandler extends NamespaceHandlerSupport {
-
- static final String CACHE_MANAGER_ATTRIBUTE = "cache-manager";
- static final String DEFAULT_CACHE_MANAGER_BEAN_NAME = "cacheManager";
-
- static String extractCacheManager(Element element) {
- return (element.hasAttribute(CacheNamespaceHandler.CACHE_MANAGER_ATTRIBUTE) ? element
- .getAttribute(CacheNamespaceHandler.CACHE_MANAGER_ATTRIBUTE)
- : CacheNamespaceHandler.DEFAULT_CACHE_MANAGER_BEAN_NAME);
- }
-
- static BeanDefinition parseKeyGenerator(Element element, BeanDefinition def) {
- String name = element.getAttribute("key-generator");
- if (StringUtils.hasText(name)) {
- def.getPropertyValues().add("keyGenerator", new RuntimeBeanReference(name.trim()));
- }
- return def;
- }
-
- public void init() {
- registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenCacheBeanDefinitionParser());
- registerBeanDefinitionParser("advice", new CacheAdviceParser());
- }
-}
+/*
+ * 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.config;
+
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+import org.springframework.util.StringUtils;
+import org.w3c.dom.Element;
+
+/**
+ * {@code NamespaceHandler} allowing for the configuration of declarative
+ * cache management using either XML or using annotations.
+ *
+ *
This namespace handler is the central piece of functionality in the
+ * Spring cache management facilities.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+public class CacheNamespaceHandler extends NamespaceHandlerSupport {
+
+ static final String CACHE_MANAGER_ATTRIBUTE = "cache-manager";
+ static final String DEFAULT_CACHE_MANAGER_BEAN_NAME = "cacheManager";
+
+ static String extractCacheManager(Element element) {
+ return (element.hasAttribute(CacheNamespaceHandler.CACHE_MANAGER_ATTRIBUTE) ? element
+ .getAttribute(CacheNamespaceHandler.CACHE_MANAGER_ATTRIBUTE)
+ : CacheNamespaceHandler.DEFAULT_CACHE_MANAGER_BEAN_NAME);
+ }
+
+ static BeanDefinition parseKeyGenerator(Element element, BeanDefinition def) {
+ String name = element.getAttribute("key-generator");
+ if (StringUtils.hasText(name)) {
+ def.getPropertyValues().add("keyGenerator", new RuntimeBeanReference(name.trim()));
+ }
+ return def;
+ }
+
+ public void init() {
+ registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenCacheBeanDefinitionParser());
+ registerBeanDefinitionParser("advice", new CacheAdviceParser());
+ }
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/config/package-info.java b/org.springframework.context/src/main/java/org/springframework/cache/config/package-info.java
index e601fd4b73c..4e44ffa83ed 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/config/package-info.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/config/package-info.java
@@ -1,9 +1,8 @@
-
-/**
- *
- * Support package for declarative caching configuration,
- * with XML schema being the primary configuration format.
- *
- */
-package org.springframework.cache.config;
-
+
+/**
+ * Support package for declarative caching configuration, with XML
+ * schema being the primary configuration format. See {@link
+ * org.springframework.cache.annotation.EnableCaching EnableCaching}
+ * for details on code-based configuration without XML.
+ */
+package org.springframework.cache.config;
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 21d1d822c82..b513e56ff4b 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,77 +1,77 @@
-/*
- * 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.ehcache;
-
-import net.sf.ehcache.Ehcache;
-import net.sf.ehcache.Element;
-import net.sf.ehcache.Status;
-
-import org.springframework.cache.Cache;
-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;
-
-
- /**
- * Create an {@link EhCacheCache} instance.
- * @param ehcache backing Ehcache instance
- */
- public EhCacheCache(Ehcache ehcache) {
- 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());
- this.cache = ehcache;
- }
-
-
- public String getName() {
- return this.cache.getName();
- }
-
- public Ehcache getNativeCache() {
- return this.cache;
- }
-
- public void clear() {
- this.cache.removeAll();
- }
-
- public ValueWrapper get(Object key) {
- Element element = this.cache.get(key);
- return (element != null ? new ValueWrapperImpl(element.getObjectValue()) : null);
- }
-
- public void put(Object key, Object value) {
- this.cache.put(new Element(key, value));
- }
-
- public void evict(Object key) {
- this.cache.remove(key);
- }
-
-}
+/*
+ * 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.ehcache;
+
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.Status;
+
+import org.springframework.cache.Cache;
+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;
+
+
+ /**
+ * Create an {@link EhCacheCache} instance.
+ * @param ehcache backing Ehcache instance
+ */
+ public EhCacheCache(Ehcache ehcache) {
+ 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());
+ this.cache = ehcache;
+ }
+
+
+ public String getName() {
+ return this.cache.getName();
+ }
+
+ public Ehcache getNativeCache() {
+ return this.cache;
+ }
+
+ public void clear() {
+ this.cache.removeAll();
+ }
+
+ public ValueWrapper get(Object key) {
+ Element element = this.cache.get(key);
+ return (element != null ? new ValueWrapperImpl(element.getObjectValue()) : null);
+ }
+
+ public void put(Object key, Object value) {
+ this.cache.put(new Element(key, value));
+ }
+
+ public void evict(Object key) {
+ this.cache.remove(key);
+ }
+
+}
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 65969a36931..2004597ef73 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,79 +1,79 @@
-/*
- * 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.ehcache;
-
-import java.util.Collection;
-import java.util.LinkedHashSet;
-
-import net.sf.ehcache.Ehcache;
-import net.sf.ehcache.Status;
-
-import org.springframework.cache.Cache;
-import org.springframework.cache.support.AbstractCacheManager;
-import org.springframework.util.Assert;
-
-/**
- * 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(this.cacheManager, "A backing EhCache CacheManager is required");
- Status status = this.cacheManager.getStatus();
- Assert.isTrue(Status.STATUS_ALIVE.equals(status),
- "An 'alive' EhCache CacheManager is required - current cache is " + status.toString());
-
- String[] names = this.cacheManager.getCacheNames();
- Collection caches = new LinkedHashSet(names.length);
- for (String name : names) {
- 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 = this.cacheManager.getEhcache(name);
- if (ehcache != null) {
- cache = new EhCacheCache(ehcache);
- addCache(cache);
- }
- }
- return cache;
- }
-
-}
+/*
+ * 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.ehcache;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Status;
+
+import org.springframework.cache.Cache;
+import org.springframework.cache.support.AbstractCacheManager;
+import org.springframework.util.Assert;
+
+/**
+ * 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(this.cacheManager, "A backing EhCache CacheManager is required");
+ Status status = this.cacheManager.getStatus();
+ Assert.isTrue(Status.STATUS_ALIVE.equals(status),
+ "An 'alive' EhCache CacheManager is required - current cache is " + status.toString());
+
+ String[] names = this.cacheManager.getCacheNames();
+ Collection caches = new LinkedHashSet(names.length);
+ for (String name : names) {
+ 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 = this.cacheManager.getEhcache(name);
+ if (ehcache != null) {
+ cache = new EhCacheCache(ehcache);
+ addCache(cache);
+ }
+ }
+ return cache;
+ }
+
+}
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 3d8568c9303..bd4de539f14 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,218 +1,221 @@
-/*
- * 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.interceptor;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.core.BridgeMethodResolver;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.ObjectUtils;
-
-/**
- * Abstract implementation of {@link CacheOperation} that caches
- * attributes for methods and implements a fallback policy: 1. specific target
- * method; 2. target class; 3. declaring method; 4. declaring class/interface.
- *
- * Defaults to using the target class's caching attribute if none is
- * associated with the target method. Any caching attribute associated with
- * the target method completely overrides a class caching attribute.
- * If none found on the target class, the interface that the invoked method
- * has been called through (in case of a JDK proxy) will be checked.
- *
- *
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
- * @since 3.1
- */
-public abstract class AbstractFallbackCacheOperationSource implements CacheOperationSource {
-
- /**
- * Canonical value held in cache to indicate no caching attribute was
- * found for this method and we don't need to look again.
- */
- private final static Collection NULL_CACHING_ATTRIBUTE = Collections.emptyList();
-
- /**
- * Logger available to subclasses.
- * As this base class is not marked Serializable, the logger will be recreated
- * after serialization - provided that the concrete subclass is Serializable.
- */
- protected final Log logger = LogFactory.getLog(getClass());
-
- /**
- * Cache of CacheOperationDefinitions, keyed by DefaultCacheKey (Method + target Class).
- *
As this base class is not marked Serializable, the cache will be recreated
- * after serialization - provided that the concrete subclass is Serializable.
- */
- 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.
- * @param method the method for the current invocation (never null)
- * @param targetClass the target class for this invocation (may be null)
- * @return {@link CacheOperation} for this method, or null if the method
- * is not cacheable
- */
- public Collection getCacheOperations(Method method, Class> targetClass) {
- // First, see if we have a cached value.
- Object cacheKey = getCacheKey(method, targetClass);
- Collection cached = this.attributeCache.get(cacheKey);
- if (cached != null) {
- if (cached == NULL_CACHING_ATTRIBUTE) {
- return null;
- }
- // Value will either be canonical value indicating there is no caching attribute,
- // or an actual caching attribute.
- return cached;
- }
- else {
- // We need to work it out.
- Collection cacheDefs = computeCacheOperationDefinition(method, targetClass);
- // Put it in the cache.
- if (cacheDefs == null) {
- this.attributeCache.put(cacheKey, NULL_CACHING_ATTRIBUTE);
- }
- else {
- if (logger.isDebugEnabled()) {
- logger.debug("Adding cacheable method '" + method.getName() + "' with attribute: " + cacheDefs);
- }
- this.attributeCache.put(cacheKey, cacheDefs);
- }
- return cacheDefs;
- }
- }
-
- /**
- * Determine a cache key for the given method and target class.
- * Must not produce same key for overloaded methods.
- * Must produce same key for different instances of the same method.
- * @param method the method (never null)
- * @param targetClass the target class (may be null)
- * @return the cache key (never null)
- */
- protected Object getCacheKey(Method method, Class> targetClass) {
- return new DefaultCacheKey(method, targetClass);
- }
-
- private Collection computeCacheOperationDefinition(Method method, Class> targetClass) {
- // Don't allow no-public methods as required.
- if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
- return null;
- }
-
- // The method may be on an interface, but we need attributes from the target class.
- // If the target class is null, the method will be unchanged.
- Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
- // If we are dealing with method with generic parameters, find the original method.
- specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
-
- // First try is the method in the target class.
- Collection opDef = findCacheOperations(specificMethod);
- if (opDef != null) {
- return opDef;
- }
-
- // Second try is the caching operation on the target class.
- opDef = findCacheOperations(specificMethod.getDeclaringClass());
- if (opDef != null) {
- return opDef;
- }
-
- if (specificMethod != method) {
- // Fall back is to look at the original method.
- opDef = findCacheOperations(method);
- if (opDef != null) {
- return opDef;
- }
- // Last fall back is the class of the original method.
- return findCacheOperations(method.getDeclaringClass());
- }
- return null;
- }
-
-
- /**
- * Subclasses need to implement this to return the caching attribute
- * for the given method, if any.
- * @param method the method to retrieve the attribute for
- * @return all caching attribute associated with this method
- * (or null if none)
- */
- protected abstract Collection findCacheOperations(Method method);
-
- /**
- * Subclasses need to implement this to return the caching attribute
- * for the given class, if any.
- * @param clazz the class to retrieve the attribute for
- * @return all caching attribute associated with this class
- * (or null if none)
- */
- protected abstract Collection findCacheOperations(Class> clazz);
-
- /**
- * Should only public methods be allowed to have caching semantics?
- * The default implementation returns false.
- */
- protected boolean allowPublicMethodsOnly() {
- return false;
- }
-
-
- /**
- * Default cache key for the CacheOperation cache.
- */
- private static class DefaultCacheKey {
-
- private final Method method;
-
- private final Class> targetClass;
-
- public DefaultCacheKey(Method method, Class> targetClass) {
- this.method = method;
- this.targetClass = targetClass;
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- }
- if (!(other instanceof DefaultCacheKey)) {
- return false;
- }
- DefaultCacheKey otherKey = (DefaultCacheKey) other;
- return (this.method.equals(otherKey.method) && ObjectUtils.nullSafeEquals(this.targetClass,
- otherKey.targetClass));
- }
-
- @Override
- public int hashCode() {
- return this.method.hashCode() * 29 + (this.targetClass != null ? this.targetClass.hashCode() : 0);
- }
- }
-}
\ No newline at end of file
+/*
+ * 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.interceptor;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.core.BridgeMethodResolver;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.ObjectUtils;
+
+/**
+ * Abstract implementation of {@link CacheOperation} that caches
+ * attributes for methods and implements a fallback policy: 1. specific
+ * target method; 2. target class; 3. declaring method; 4. declaring
+ * class/interface.
+ *
+ *
Defaults to using the target class's caching attribute if none is
+ * associated with the target method. Any caching attribute associated
+ * with the target method completely overrides a class caching attribute.
+ * If none found on the target class, the interface that the invoked
+ * method has been called through (in case of a JDK proxy) will be
+ * checked.
+ *
+ *
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
+ * @since 3.1
+ */
+public abstract class AbstractFallbackCacheOperationSource implements CacheOperationSource {
+
+ /**
+ * Canonical value held in cache to indicate no caching attribute was
+ * found for this method and we don't need to look again.
+ */
+ private final static Collection NULL_CACHING_ATTRIBUTE = Collections.emptyList();
+
+ /**
+ * Logger available to subclasses.
+ * As this base class is not marked Serializable, the logger will be recreated
+ * after serialization - provided that the concrete subclass is Serializable.
+ */
+ protected final Log logger = LogFactory.getLog(getClass());
+
+ /**
+ * Cache of CacheOperationDefinitions, keyed by DefaultCacheKey (Method + target Class).
+ *
As this base class is not marked Serializable, the cache will be recreated
+ * after serialization - provided that the concrete subclass is Serializable.
+ */
+ 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.
+ * @param method the method for the current invocation (never {@code null})
+ * @param targetClass the target class for this invocation (may be {@code null})
+ * @return {@link CacheOperation} for this method, or {@code null} if the method
+ * is not cacheable
+ */
+ public Collection getCacheOperations(Method method, Class> targetClass) {
+ // First, see if we have a cached value.
+ Object cacheKey = getCacheKey(method, targetClass);
+ Collection cached = this.attributeCache.get(cacheKey);
+ if (cached != null) {
+ if (cached == NULL_CACHING_ATTRIBUTE) {
+ return null;
+ }
+ // Value will either be canonical value indicating there is no caching attribute,
+ // or an actual caching attribute.
+ return cached;
+ }
+ else {
+ // We need to work it out.
+ Collection cacheDefs = computeCacheOperationDefinition(method, targetClass);
+ // Put it in the cache.
+ if (cacheDefs == null) {
+ this.attributeCache.put(cacheKey, NULL_CACHING_ATTRIBUTE);
+ }
+ else {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Adding cacheable method '" + method.getName() + "' with attribute: " + cacheDefs);
+ }
+ this.attributeCache.put(cacheKey, cacheDefs);
+ }
+ return cacheDefs;
+ }
+ }
+
+ /**
+ * Determine a cache key for the given method and target class.
+ * Must not produce same key for overloaded methods.
+ * Must produce same key for different instances of the same method.
+ * @param method the method (never {@code null})
+ * @param targetClass the target class (may be {@code null})
+ * @return the cache key (never {@code null})
+ */
+ protected Object getCacheKey(Method method, Class> targetClass) {
+ return new DefaultCacheKey(method, targetClass);
+ }
+
+ private Collection computeCacheOperationDefinition(Method method, Class> targetClass) {
+ // Don't allow no-public methods as required.
+ if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
+ return null;
+ }
+
+ // The method may be on an interface, but we need attributes from the target class.
+ // If the target class is null, the method will be unchanged.
+ Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
+ // If we are dealing with method with generic parameters, find the original method.
+ specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
+
+ // First try is the method in the target class.
+ Collection opDef = findCacheOperations(specificMethod);
+ if (opDef != null) {
+ return opDef;
+ }
+
+ // Second try is the caching operation on the target class.
+ opDef = findCacheOperations(specificMethod.getDeclaringClass());
+ if (opDef != null) {
+ return opDef;
+ }
+
+ if (specificMethod != method) {
+ // Fall back is to look at the original method.
+ opDef = findCacheOperations(method);
+ if (opDef != null) {
+ return opDef;
+ }
+ // Last fall back is the class of the original method.
+ return findCacheOperations(method.getDeclaringClass());
+ }
+ return null;
+ }
+
+
+ /**
+ * Subclasses need to implement this to return the caching attribute
+ * for the given method, if any.
+ * @param method the method to retrieve the attribute for
+ * @return all caching attribute associated with this method
+ * (or {@code null} if none)
+ */
+ protected abstract Collection findCacheOperations(Method method);
+
+ /**
+ * Subclasses need to implement this to return the caching attribute
+ * for the given class, if any.
+ * @param clazz the class to retrieve the attribute for
+ * @return all caching attribute associated with this class
+ * (or {@code null} if none)
+ */
+ protected abstract Collection findCacheOperations(Class> clazz);
+
+ /**
+ * Should only public methods be allowed to have caching semantics?
+ * The default implementation returns {@code false}.
+ */
+ protected boolean allowPublicMethodsOnly() {
+ return false;
+ }
+
+
+ /**
+ * Default cache key for the CacheOperation cache.
+ */
+ private static class DefaultCacheKey {
+
+ private final Method method;
+
+ private final Class> targetClass;
+
+ public DefaultCacheKey(Method method, Class> targetClass) {
+ this.method = method;
+ this.targetClass = targetClass;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof DefaultCacheKey)) {
+ return false;
+ }
+ DefaultCacheKey otherKey = (DefaultCacheKey) other;
+ return (this.method.equals(otherKey.method) && ObjectUtils.nullSafeEquals(this.targetClass,
+ otherKey.targetClass));
+ }
+
+ @Override
+ public int hashCode() {
+ return this.method.hashCode() * 29 + (this.targetClass != null ? this.targetClass.hashCode() : 0);
+ }
+ }
+}
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 9e51071f4c7..97cb34d624b 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,65 +1,65 @@
-/*
- * 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.interceptor;
-
-import org.springframework.aop.ClassFilter;
-import org.springframework.aop.Pointcut;
-import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
-
-/**
- * Advisor driven by a {@link CacheOperationSource}, used to include a
- * cache advice bean for methods that are cacheable.
- *
- * @author Costin Leau
- * @since 3.1
- */
-@SuppressWarnings("serial")
-public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
-
- private CacheOperationSource cacheOperationSource;
-
- private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
- @Override
- protected CacheOperationSource getCacheOperationSource() {
- 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 setCacheOperationSource(CacheOperationSource cacheOperationSource) {
- this.cacheOperationSource = cacheOperationSource;
- }
-
- /**
- * Set the {@link ClassFilter} to use for this pointcut.
- * Default is {@link ClassFilter#TRUE}.
- */
- public void setClassFilter(ClassFilter classFilter) {
- this.pointcut.setClassFilter(classFilter);
- }
-
- public Pointcut getPointcut() {
- return this.pointcut;
- }
-
-}
+/*
+ * 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.interceptor;
+
+import org.springframework.aop.ClassFilter;
+import org.springframework.aop.Pointcut;
+import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;
+
+/**
+ * Advisor driven by a {@link CacheOperationSource}, used to include a
+ * cache advice bean for methods that are cacheable.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+@SuppressWarnings("serial")
+public class BeanFactoryCacheOperationSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
+
+ private CacheOperationSource cacheOperationSource;
+
+ private final CacheOperationSourcePointcut pointcut = new CacheOperationSourcePointcut() {
+ @Override
+ protected CacheOperationSource getCacheOperationSource() {
+ 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 setCacheOperationSource(CacheOperationSource cacheOperationSource) {
+ this.cacheOperationSource = cacheOperationSource;
+ }
+
+ /**
+ * Set the {@link ClassFilter} to use for this pointcut.
+ * Default is {@link ClassFilter#TRUE}.
+ */
+ public void setClassFilter(ClassFilter classFilter) {
+ this.pointcut.setClassFilter(classFilter);
+ }
+
+ public Pointcut getPointcut() {
+ return this.pointcut;
+ }
+
+}
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 c1b7e703903..8fcaeab717b 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,463 +1,465 @@
-/*
- * 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.interceptor;
-
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-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.expression.EvaluationContext;
-import org.springframework.util.Assert;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
-/**
- * Base class for caching aspects, such as the {@link CacheInterceptor}
- * or an AspectJ aspect.
- *
- *
This enables the underlying Spring caching infrastructure to be used easily
- * to implement an aspect for any aspect system.
- *
- *
Subclasses are responsible for calling methods in this class in the correct order.
- *
- *
Uses the Strategy design pattern. A {@link CacheManager} implementation will
- * perform the actual cache management, and a {@link CacheOperationSource} is used for
- * determining caching operation definitions.
- *
- *
A cache aspect is serializable if its {@code CacheManager} and
- * {@code CacheOperationSource} are serializable.
- *
- * @author Costin Leau
- * @author Juergen Hoeller
- * @author Chris Beams
- * @since 3.1
- */
-public abstract class CacheAspectSupport implements InitializingBean {
-
- public interface Invoker {
- Object invoke();
- }
-
- protected final Log logger = LogFactory.getLog(getClass());
-
- private CacheManager cacheManager;
-
- private CacheOperationSource cacheOperationSource;
-
- private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
-
- private KeyGenerator keyGenerator = new DefaultKeyGenerator();
-
- private boolean initialized = false;
-
- private static final String CACHEABLE = "cacheable", UPDATE = "cacheupdate", EVICT = "cacheevict";
-
- /**
- * 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 one or more cache definition sources which are used to find the cache
- * attributes. If more than one source is provided, they will be aggregated using a
- * {@link CompositeCacheOperationSource}.
- * @param cacheOperationSources must not be {@code null}
- */
- public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) {
- Assert.notEmpty(cacheOperationSources);
- this.cacheOperationSource =
- (cacheOperationSources.length > 1 ?
- new CompositeCacheOperationSource(cacheOperationSources) :
- cacheOperationSources[0]);
- }
-
- /**
- * 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("'cacheManager' is required");
- }
- 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.");
- }
-
- 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
- * different identifier for the given method.
- * @param method the method we're interested in
- * @param targetClass class the method is on
- * @return log message identifying this method
- * @see org.springframework.util.ClassUtils#getQualifiedMethodName
- */
- protected String methodIdentification(Method method, Class> targetClass) {
- Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
- return ClassUtils.getQualifiedMethodName(specificMethod);
- }
-
- protected Collection getCaches(CacheOperation operation) {
- Set cacheNames = operation.getCacheNames();
- Collection caches = new ArrayList(cacheNames.size());
- for (String cacheName : cacheNames) {
- 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(Invoker invoker, Object target, Method method, Object[] args) {
- // check whether aspect is enabled
- // to cope with cases where the AJ is pulled in automatically
- if (!this.initialized) {
- return invoker.invoke();
- }
-
- // get backing class
- Class> targetClass = AopProxyUtils.ultimateTargetClass(target);
- if (targetClass == null && target != null) {
- targetClass = target.getClass();
- }
- final Collection cacheOp = getCacheOperationSource().getCacheOperations(method, targetClass);
-
- // analyze caching information
- if (!CollectionUtils.isEmpty(cacheOp)) {
- Map> ops = createOperationContext(cacheOp, method, args, target,
- targetClass);
-
- // start with evictions
- inspectCacheEvicts(ops.get(EVICT));
-
- // follow up with cacheable
- CacheStatus status = inspectCacheables(ops.get(CACHEABLE));
-
- Object retVal = null;
- Map updates = inspectCacheUpdates(ops.get(UPDATE));
-
- if (status != null) {
- if (status.updateRequired) {
- updates.putAll(status.cUpdates);
- }
- // return cached object
- else {
- return status.retVal;
- }
- }
-
- retVal = invoker.invoke();
-
- if (!updates.isEmpty()) {
- update(updates, retVal);
- }
-
- return retVal;
- }
-
- return invoker.invoke();
- }
-
- private void inspectCacheEvicts(Collection evictions) {
-
- if (!evictions.isEmpty()) {
-
- boolean log = logger.isTraceEnabled();
-
- for (CacheOperationContext context : evictions) {
- if (context.isConditionPassing()) {
- CacheEvictOperation evictOp = (CacheEvictOperation) context.operation;
-
- // for each cache
- // lazy key initialization
- Object key = null;
-
- for (Cache cache : context.getCaches()) {
- // cache-wide flush
- if (evictOp.isCacheWide()) {
- cache.clear();
- if (log) {
- logger.trace("Invalidating entire cache for definition " + evictOp + " on method " + context.method);
- }
- } else {
- // check key
- if (key == null) {
- key = context.generateKey();
- }
- if (log) {
- logger.trace("Invalidating cache key " + key + " for definition " + evictOp + " on method " + context.method);
- }
- cache.evict(key);
- }
- }
- }
- else {
- if (log) {
- logger.trace("Cache condition failed on method " + context.method + " for definition " + context.operation);
- }
- }
- }
- }
- }
-
- private CacheStatus inspectCacheables(Collection cacheables) {
- Map cUpdates = new LinkedHashMap(
- cacheables.size());
-
- boolean updateRequire = false;
- Object retVal = null;
-
- if (!cacheables.isEmpty()) {
- boolean log = logger.isTraceEnabled();
- boolean atLeastOnePassed = false;
-
- for (CacheOperationContext context : cacheables) {
- if (context.isConditionPassing()) {
- atLeastOnePassed = true;
- Object key = context.generateKey();
-
- if (log) {
- logger.trace("Computed cache key " + key + " for definition " + context.operation);
- }
- if (key == null) {
- throw new IllegalArgumentException(
- "Null key returned for cache definition (maybe you are using named params on classes without debug info?) "
- + context.operation);
- }
-
- // add op/key (in case an update is discovered later on)
- cUpdates.put(context, key);
-
- boolean localCacheHit = false;
-
- // check whether the cache needs to be inspected or not (the method will be invoked anyway)
- if (!updateRequire) {
- for (Cache cache : context.getCaches()) {
- Cache.ValueWrapper wrapper = cache.get(key);
- if (wrapper != null) {
- retVal = wrapper.get();
- localCacheHit = true;
- break;
- }
- }
- }
-
- if (!localCacheHit) {
- updateRequire = true;
- }
- }
- else {
- if (log) {
- logger.trace("Cache condition failed on method " + context.method + " for definition " + context.operation);
- }
- }
- }
-
- // return a status only if at least on cacheable matched
- if (atLeastOnePassed) {
- return new CacheStatus(cUpdates, updateRequire, retVal);
- }
- }
-
- return null;
- }
-
- private static class CacheStatus {
- // caches/key
- final Map cUpdates;
- final boolean updateRequired;
- final Object retVal;
-
- CacheStatus(Map cUpdates, boolean updateRequired, Object retVal) {
- this.cUpdates = cUpdates;
- this.updateRequired = updateRequired;
- this.retVal = retVal;
- }
- }
-
- private Map inspectCacheUpdates(Collection updates) {
-
- Map cUpdates = new LinkedHashMap(updates.size());
-
- if (!updates.isEmpty()) {
- boolean log = logger.isTraceEnabled();
-
- for (CacheOperationContext context : updates) {
- if (context.isConditionPassing()) {
-
- Object key = context.generateKey();
-
- if (log) {
- logger.trace("Computed cache key " + key + " for definition " + context.operation);
- }
- if (key == null) {
- throw new IllegalArgumentException(
- "Null key returned for cache definition (maybe you are using named params on classes without debug info?) "
- + context.operation);
- }
-
- // add op/key (in case an update is discovered later on)
- cUpdates.put(context, key);
- }
- else {
- if (log) {
- logger.trace("Cache condition failed on method " + context.method + " for definition " + context.operation);
- }
- }
- }
- }
-
- return cUpdates;
- }
-
- private void update(Map updates, Object retVal) {
- for (Map.Entry entry : updates.entrySet()) {
- for (Cache cache : entry.getKey().getCaches()) {
- cache.put(entry.getValue(), retVal);
- }
- }
- }
-
- private Map> createOperationContext(Collection cacheOp,
- Method method, Object[] args, Object target, Class> targetClass) {
- Map> map = new LinkedHashMap>(3);
-
- Collection cacheables = new ArrayList();
- Collection evicts = new ArrayList();
- Collection updates = new ArrayList();
-
- for (CacheOperation cacheOperation : cacheOp) {
- CacheOperationContext opContext = getOperationContext(cacheOperation, method, args, target, targetClass);
-
- if (cacheOperation instanceof CacheableOperation) {
- cacheables.add(opContext);
- }
-
- if (cacheOperation instanceof CacheEvictOperation) {
- evicts.add(opContext);
- }
-
- if (cacheOperation instanceof CachePutOperation) {
- updates.add(opContext);
- }
- }
-
- map.put(CACHEABLE, cacheables);
- map.put(EVICT, evicts);
- map.put(UPDATE, updates);
-
- return map;
- }
-
- protected class CacheOperationContext {
-
- 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;
-
- public CacheOperationContext(CacheOperation operation, Method method, Object[] args, Object target,
- Class> targetClass) {
- this.operation = operation;
- this.caches = CacheAspectSupport.this.getCaches(operation);
- this.target = target;
- this.method = method;
- this.args = args;
-
- this.evalContext = evaluator.createEvaluationContext(caches, method, args, target, targetClass);
- }
-
- protected boolean isConditionPassing() {
- 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 operation.
- * @return generated key (null if none can be generated)
- */
- protected Object generateKey() {
- if (StringUtils.hasText(this.operation.getKey())) {
- return evaluator.key(this.operation.getKey(), this.method, this.evalContext);
- }
- return keyGenerator.generate(this.target, this.method, this.args);
- }
-
- protected Collection getCaches() {
- return this.caches;
- }
- }
-}
\ No newline at end of file
+/*
+ * 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.interceptor;
+
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+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.expression.EvaluationContext;
+import org.springframework.util.Assert;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+/**
+ * Base class for caching aspects, such as the {@link CacheInterceptor}
+ * or an AspectJ aspect.
+ *
+ * This enables the underlying Spring caching infrastructure to be
+ * used easily to implement an aspect for any aspect system.
+ *
+ *
Subclasses are responsible for calling methods in this class in
+ * the correct order.
+ *
+ *
Uses the Strategy design pattern. A {@link CacheManager}
+ * implementation will perform the actual cache management, and a
+ * {@link CacheOperationSource} is used for determining caching
+ * operation definitions.
+ *
+ *
A cache aspect is serializable if its {@code CacheManager} and
+ * {@code CacheOperationSource} are serializable.
+ *
+ * @author Costin Leau
+ * @author Juergen Hoeller
+ * @author Chris Beams
+ * @since 3.1
+ */
+public abstract class CacheAspectSupport implements InitializingBean {
+
+ public interface Invoker {
+ Object invoke();
+ }
+
+ protected final Log logger = LogFactory.getLog(getClass());
+
+ private CacheManager cacheManager;
+
+ private CacheOperationSource cacheOperationSource;
+
+ private final ExpressionEvaluator evaluator = new ExpressionEvaluator();
+
+ private KeyGenerator keyGenerator = new DefaultKeyGenerator();
+
+ private boolean initialized = false;
+
+ private static final String CACHEABLE = "cacheable", UPDATE = "cacheupdate", EVICT = "cacheevict";
+
+ /**
+ * 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 one or more cache definition sources which are used to find the cache
+ * attributes. If more than one source is provided, they will be aggregated using a
+ * {@link CompositeCacheOperationSource}.
+ * @param cacheOperationSources must not be {@code null}
+ */
+ public void setCacheOperationSources(CacheOperationSource... cacheOperationSources) {
+ Assert.notEmpty(cacheOperationSources);
+ this.cacheOperationSource =
+ (cacheOperationSources.length > 1 ?
+ new CompositeCacheOperationSource(cacheOperationSources) :
+ cacheOperationSources[0]);
+ }
+
+ /**
+ * 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("'cacheManager' is required");
+ }
+ 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.");
+ }
+
+ 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
+ * different identifier for the given method.
+ * @param method the method we're interested in
+ * @param targetClass class the method is on
+ * @return log message identifying this method
+ * @see org.springframework.util.ClassUtils#getQualifiedMethodName
+ */
+ protected String methodIdentification(Method method, Class> targetClass) {
+ Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
+ return ClassUtils.getQualifiedMethodName(specificMethod);
+ }
+
+ protected Collection getCaches(CacheOperation operation) {
+ Set cacheNames = operation.getCacheNames();
+ Collection caches = new ArrayList(cacheNames.size());
+ for (String cacheName : cacheNames) {
+ 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(Invoker invoker, Object target, Method method, Object[] args) {
+ // check whether aspect is enabled
+ // to cope with cases where the AJ is pulled in automatically
+ if (!this.initialized) {
+ return invoker.invoke();
+ }
+
+ // get backing class
+ Class> targetClass = AopProxyUtils.ultimateTargetClass(target);
+ if (targetClass == null && target != null) {
+ targetClass = target.getClass();
+ }
+ final Collection cacheOp = getCacheOperationSource().getCacheOperations(method, targetClass);
+
+ // analyze caching information
+ if (!CollectionUtils.isEmpty(cacheOp)) {
+ Map> ops = createOperationContext(cacheOp, method, args, target,
+ targetClass);
+
+ // start with evictions
+ inspectCacheEvicts(ops.get(EVICT));
+
+ // follow up with cacheable
+ CacheStatus status = inspectCacheables(ops.get(CACHEABLE));
+
+ Object retVal = null;
+ Map updates = inspectCacheUpdates(ops.get(UPDATE));
+
+ if (status != null) {
+ if (status.updateRequired) {
+ updates.putAll(status.cUpdates);
+ }
+ // return cached object
+ else {
+ return status.retVal;
+ }
+ }
+
+ retVal = invoker.invoke();
+
+ if (!updates.isEmpty()) {
+ update(updates, retVal);
+ }
+
+ return retVal;
+ }
+
+ return invoker.invoke();
+ }
+
+ private void inspectCacheEvicts(Collection evictions) {
+
+ if (!evictions.isEmpty()) {
+
+ boolean log = logger.isTraceEnabled();
+
+ for (CacheOperationContext context : evictions) {
+ if (context.isConditionPassing()) {
+ CacheEvictOperation evictOp = (CacheEvictOperation) context.operation;
+
+ // for each cache
+ // lazy key initialization
+ Object key = null;
+
+ for (Cache cache : context.getCaches()) {
+ // cache-wide flush
+ if (evictOp.isCacheWide()) {
+ cache.clear();
+ if (log) {
+ logger.trace("Invalidating entire cache for definition " + evictOp + " on method " + context.method);
+ }
+ } else {
+ // check key
+ if (key == null) {
+ key = context.generateKey();
+ }
+ if (log) {
+ logger.trace("Invalidating cache key " + key + " for definition " + evictOp + " on method " + context.method);
+ }
+ cache.evict(key);
+ }
+ }
+ }
+ else {
+ if (log) {
+ logger.trace("Cache condition failed on method " + context.method + " for definition " + context.operation);
+ }
+ }
+ }
+ }
+ }
+
+ private CacheStatus inspectCacheables(Collection cacheables) {
+ Map cUpdates = new LinkedHashMap(
+ cacheables.size());
+
+ boolean updateRequire = false;
+ Object retVal = null;
+
+ if (!cacheables.isEmpty()) {
+ boolean log = logger.isTraceEnabled();
+ boolean atLeastOnePassed = false;
+
+ for (CacheOperationContext context : cacheables) {
+ if (context.isConditionPassing()) {
+ atLeastOnePassed = true;
+ Object key = context.generateKey();
+
+ if (log) {
+ logger.trace("Computed cache key " + key + " for definition " + context.operation);
+ }
+ if (key == null) {
+ throw new IllegalArgumentException(
+ "Null key returned for cache definition (maybe you are using named params on classes without debug info?) "
+ + context.operation);
+ }
+
+ // add op/key (in case an update is discovered later on)
+ cUpdates.put(context, key);
+
+ boolean localCacheHit = false;
+
+ // check whether the cache needs to be inspected or not (the method will be invoked anyway)
+ if (!updateRequire) {
+ for (Cache cache : context.getCaches()) {
+ Cache.ValueWrapper wrapper = cache.get(key);
+ if (wrapper != null) {
+ retVal = wrapper.get();
+ localCacheHit = true;
+ break;
+ }
+ }
+ }
+
+ if (!localCacheHit) {
+ updateRequire = true;
+ }
+ }
+ else {
+ if (log) {
+ logger.trace("Cache condition failed on method " + context.method + " for definition " + context.operation);
+ }
+ }
+ }
+
+ // return a status only if at least on cacheable matched
+ if (atLeastOnePassed) {
+ return new CacheStatus(cUpdates, updateRequire, retVal);
+ }
+ }
+
+ return null;
+ }
+
+ private static class CacheStatus {
+ // caches/key
+ final Map cUpdates;
+ final boolean updateRequired;
+ final Object retVal;
+
+ CacheStatus(Map cUpdates, boolean updateRequired, Object retVal) {
+ this.cUpdates = cUpdates;
+ this.updateRequired = updateRequired;
+ this.retVal = retVal;
+ }
+ }
+
+ private Map inspectCacheUpdates(Collection updates) {
+
+ Map cUpdates = new LinkedHashMap(updates.size());
+
+ if (!updates.isEmpty()) {
+ boolean log = logger.isTraceEnabled();
+
+ for (CacheOperationContext context : updates) {
+ if (context.isConditionPassing()) {
+
+ Object key = context.generateKey();
+
+ if (log) {
+ logger.trace("Computed cache key " + key + " for definition " + context.operation);
+ }
+ if (key == null) {
+ throw new IllegalArgumentException(
+ "Null key returned for cache definition (maybe you are using named params on classes without debug info?) "
+ + context.operation);
+ }
+
+ // add op/key (in case an update is discovered later on)
+ cUpdates.put(context, key);
+ }
+ else {
+ if (log) {
+ logger.trace("Cache condition failed on method " + context.method + " for definition " + context.operation);
+ }
+ }
+ }
+ }
+
+ return cUpdates;
+ }
+
+ private void update(Map updates, Object retVal) {
+ for (Map.Entry entry : updates.entrySet()) {
+ for (Cache cache : entry.getKey().getCaches()) {
+ cache.put(entry.getValue(), retVal);
+ }
+ }
+ }
+
+ private Map> createOperationContext(Collection cacheOp,
+ Method method, Object[] args, Object target, Class> targetClass) {
+ Map> map = new LinkedHashMap>(3);
+
+ Collection cacheables = new ArrayList();
+ Collection evicts = new ArrayList();
+ Collection updates = new ArrayList();
+
+ for (CacheOperation cacheOperation : cacheOp) {
+ CacheOperationContext opContext = getOperationContext(cacheOperation, method, args, target, targetClass);
+
+ if (cacheOperation instanceof CacheableOperation) {
+ cacheables.add(opContext);
+ }
+
+ if (cacheOperation instanceof CacheEvictOperation) {
+ evicts.add(opContext);
+ }
+
+ if (cacheOperation instanceof CachePutOperation) {
+ updates.add(opContext);
+ }
+ }
+
+ map.put(CACHEABLE, cacheables);
+ map.put(EVICT, evicts);
+ map.put(UPDATE, updates);
+
+ return map;
+ }
+
+ protected class CacheOperationContext {
+
+ 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;
+
+ public CacheOperationContext(CacheOperation operation, Method method, Object[] args, Object target,
+ Class> targetClass) {
+ this.operation = operation;
+ this.caches = CacheAspectSupport.this.getCaches(operation);
+ this.target = target;
+ this.method = method;
+ this.args = args;
+
+ this.evalContext = evaluator.createEvaluationContext(caches, method, args, target, targetClass);
+ }
+
+ protected boolean isConditionPassing() {
+ 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 operation.
+ * @return generated key (null if none can be generated)
+ */
+ protected Object generateKey() {
+ if (StringUtils.hasText(this.operation.getKey())) {
+ return evaluator.key(this.operation.getKey(), this.method, this.evalContext);
+ }
+ return keyGenerator.generate(this.target, this.method, this.args);
+ }
+
+ protected Collection getCaches() {
+ return this.caches;
+ }
+ }
+}
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 c9c47dcd521..d9efe270914 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,44 +1,44 @@
-/*
- * 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.interceptor;
-
-/**
- * Class describing a cache 'evict' operation.
- *
- * @author Costin Leau
- * @since 3.1
- */
-public class CacheEvictOperation extends CacheOperation {
-
- private boolean cacheWide = false;
-
- 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(this.cacheWide);
- return sb;
- }
-}
+/*
+ * 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.interceptor;
+
+/**
+ * Class describing a cache 'evict' operation.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+public class CacheEvictOperation extends CacheOperation {
+
+ private boolean cacheWide = false;
+
+ 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(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 af534a476bf..525cf043d7f 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,81 +1,81 @@
-/*
- * 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.interceptor;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-
-import org.springframework.cache.Cache;
-import org.springframework.util.Assert;
-
-/**
- * Class describing the root object used during the expression evaluation.
- *
- * @author Costin Leau
- * @since 3.1
- */
-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;
- }
-
-}
+/*
+ * 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.interceptor;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+
+import org.springframework.cache.Cache;
+import org.springframework.util.Assert;
+
+/**
+ * Class describing the root object used during the expression evaluation.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+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 a6f9836c82c..9358a5b07cb 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,71 +1,71 @@
-/*
- * 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.interceptor;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.aopalliance.intercept.MethodInterceptor;
-import org.aopalliance.intercept.MethodInvocation;
-
-/**
- * AOP Alliance MethodInterceptor for declarative cache
- * management using the common Spring caching infrastructure
- * ({@link org.springframework.cache.Cache}).
- *
- * Derives from the {@link CacheAspectSupport} class which
- * contains the integration with Spring's underlying caching API.
- * CacheInterceptor simply calls the relevant superclass methods
- * 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 {
-
- private static class ThrowableWrapper extends RuntimeException {
- private final Throwable original;
-
- ThrowableWrapper(Throwable original) {
- this.original = original;
- }
- }
-
- public Object invoke(final MethodInvocation invocation) throws Throwable {
- Method method = invocation.getMethod();
-
- Invoker aopAllianceInvoker = new Invoker() {
- public Object invoke() {
- try {
- return invocation.proceed();
- } catch (Throwable ex) {
- throw new ThrowableWrapper(ex);
- }
- }
- };
-
- try {
- return execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments());
- } catch (ThrowableWrapper th) {
- throw th.original;
- }
- }
-}
\ No newline at end of file
+/*
+ * 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.interceptor;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.aopalliance.intercept.MethodInterceptor;
+import org.aopalliance.intercept.MethodInvocation;
+
+/**
+ * AOP Alliance MethodInterceptor for declarative cache
+ * management using the common Spring caching infrastructure
+ * ({@link org.springframework.cache.Cache}).
+ *
+ *
Derives from the {@link CacheAspectSupport} class which
+ * contains the integration with Spring's underlying caching API.
+ * CacheInterceptor simply calls the relevant superclass methods
+ * 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 {
+
+ private static class ThrowableWrapper extends RuntimeException {
+ private final Throwable original;
+
+ ThrowableWrapper(Throwable original) {
+ this.original = original;
+ }
+ }
+
+ public Object invoke(final MethodInvocation invocation) throws Throwable {
+ Method method = invocation.getMethod();
+
+ Invoker aopAllianceInvoker = new Invoker() {
+ public Object invoke() {
+ try {
+ return invocation.proceed();
+ } catch (Throwable ex) {
+ throw new ThrowableWrapper(ex);
+ }
+ }
+ };
+
+ try {
+ return execute(aopAllianceInvoker, invocation.getThis(), method, invocation.getArguments());
+ } catch (ThrowableWrapper th) {
+ throw th.original;
+ }
+ }
+}
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 9a06a457bde..c9a5fce4e0b 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,128 +1,128 @@
-/*
- * 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.interceptor;
-
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-import org.springframework.util.Assert;
-
-/**
- * Base class implementing {@link CacheOperation}.
- *
- * @author Costin Leau
- */
-public abstract class CacheOperation {
-
- private Set cacheNames = Collections.emptySet();
- private String condition = "";
- private String key = "";
- private String name = "";
-
-
- public Set getCacheNames() {
- return cacheNames;
- }
-
- public String getCondition() {
- return condition;
- }
-
- public String getKey() {
- return key;
- }
-
- public String getName() {
- return name;
- }
-
- public void setCacheName(String cacheName) {
- Assert.hasText(cacheName);
- this.cacheNames = Collections.singleton(cacheName);
- }
-
- public void setCacheNames(String[] cacheNames) {
- Assert.notEmpty(cacheNames);
- this.cacheNames = new LinkedHashSet(cacheNames.length);
- for (String string : cacheNames) {
- this.cacheNames.add(string);
- }
- }
-
- public void setCondition(String condition) {
- Assert.notNull(condition);
- this.condition = condition;
- }
-
- public void setKey(String key) {
- Assert.notNull(key);
- this.key = key;
- }
-
- public void setName(String name) {
- Assert.hasText(name);
- this.name = name;
- }
-
- /**
- * This implementation compares the toString() results.
- * @see #toString()
- */
- @Override
- public boolean equals(Object other) {
- return (other instanceof CacheOperation && toString().equals(other.toString()));
- }
-
- /**
- * This implementation returns toString()'s hash code.
- * @see #toString()
- */
- @Override
- public int hashCode() {
- return toString().hashCode();
- }
-
- /**
- * Return an identifying description for this cache operation.
- * Has to be overridden in subclasses for correct equals
- * and hashCode behavior. Alternatively, {@link #equals}
- * and {@link #hashCode} can be overridden themselves.
- */
- @Override
- public String toString() {
- return getOperationDescription().toString();
- }
-
- /**
- * Return an identifying description for this caching operation.
- *
Available to subclasses, for inclusion in their toString() result.
- */
- protected StringBuilder getOperationDescription() {
- StringBuilder result = new StringBuilder();
- result.append("CacheDefinition[");
- result.append(this.name);
- result.append("] caches=");
- result.append(this.cacheNames);
- result.append(" | condition='");
- result.append(this.condition);
- result.append("' | key='");
- result.append(this.key);
- result.append("'");
- return result;
- }
-}
\ No newline at end of file
+/*
+ * 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.interceptor;
+
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.springframework.util.Assert;
+
+/**
+ * Base class implementing {@link CacheOperation}.
+ *
+ * @author Costin Leau
+ */
+public abstract class CacheOperation {
+
+ private Set cacheNames = Collections.emptySet();
+ private String condition = "";
+ private String key = "";
+ private String name = "";
+
+
+ public Set getCacheNames() {
+ return cacheNames;
+ }
+
+ public String getCondition() {
+ return condition;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setCacheName(String cacheName) {
+ Assert.hasText(cacheName);
+ this.cacheNames = Collections.singleton(cacheName);
+ }
+
+ public void setCacheNames(String[] cacheNames) {
+ Assert.notEmpty(cacheNames);
+ this.cacheNames = new LinkedHashSet(cacheNames.length);
+ for (String string : cacheNames) {
+ this.cacheNames.add(string);
+ }
+ }
+
+ public void setCondition(String condition) {
+ Assert.notNull(condition);
+ this.condition = condition;
+ }
+
+ public void setKey(String key) {
+ Assert.notNull(key);
+ this.key = key;
+ }
+
+ public void setName(String name) {
+ Assert.hasText(name);
+ this.name = name;
+ }
+
+ /**
+ * This implementation compares the {@code toString()} results.
+ * @see #toString()
+ */
+ @Override
+ public boolean equals(Object other) {
+ return (other instanceof CacheOperation && toString().equals(other.toString()));
+ }
+
+ /**
+ * This implementation returns {@code toString()}'s hash code.
+ * @see #toString()
+ */
+ @Override
+ public int hashCode() {
+ return toString().hashCode();
+ }
+
+ /**
+ * Return an identifying description for this cache operation.
+ * Has to be overridden in subclasses for correct {@code equals}
+ * and {@code hashCode} behavior. Alternatively, {@link #equals}
+ * and {@link #hashCode} can be overridden themselves.
+ */
+ @Override
+ public String toString() {
+ return getOperationDescription().toString();
+ }
+
+ /**
+ * Return an identifying description for this caching operation.
+ *
Available to subclasses, for inclusion in their {@code toString()} result.
+ */
+ protected StringBuilder getOperationDescription() {
+ StringBuilder result = new StringBuilder();
+ result.append("CacheDefinition[");
+ result.append(this.name);
+ result.append("] caches=");
+ result.append(this.cacheNames);
+ result.append(" | condition='");
+ result.append(this.condition);
+ 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 7d45ec504df..fb75394d6ca 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,43 +1,43 @@
-/*
- * 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.interceptor;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-
-/**
- * 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,
- * or null if the method contains no "cacheable" annotations.
- * @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
- */
- Collection getCacheOperations(Method method, Class> targetClass);
-
-}
+/*
+ * 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.interceptor;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+
+/**
+ * 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,
+ * or {@code null} if the method contains no "cacheable" annotations.
+ * @param method the method to introspect
+ * @param targetClass the target class (may be {@code null},
+ * in which case the declaring class of the method must be used)
+ * @return {@link CacheOperation} the matching cache operation,
+ * or {@code null} if none found
+ */
+ Collection getCacheOperations(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 9f357431100..7fd2bb3d43c 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,71 +1,71 @@
-/*
- * 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.interceptor;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-import org.springframework.aop.support.StaticMethodMatcherPointcut;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.ObjectUtils;
-
-/**
- * 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 {
-
- public boolean matches(Method method, Class> targetClass) {
- CacheOperationSource cas = getCacheOperationSource();
- return (cas != null && !CollectionUtils.isEmpty(cas.getCacheOperations(method, targetClass)));
- }
-
- @Override
- public boolean equals(Object other) {
- if (this == other) {
- return true;
- }
- if (!(other instanceof CacheOperationSourcePointcut)) {
- return false;
- }
- CacheOperationSourcePointcut otherPc = (CacheOperationSourcePointcut) other;
- return ObjectUtils.nullSafeEquals(getCacheOperationSource(),
- otherPc.getCacheOperationSource());
- }
-
- @Override
- public int hashCode() {
- return CacheOperationSourcePointcut.class.hashCode();
- }
-
- @Override
- public String toString() {
- return getClass().getName() + ": " + getCacheOperationSource();
- }
-
-
- /**
- * Obtain the underlying CacheOperationDefinitionSource (may be null).
- * To be implemented by subclasses.
- */
- protected abstract CacheOperationSource getCacheOperationSource();
-
-}
+/*
+ * 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.interceptor;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+import org.springframework.aop.support.StaticMethodMatcherPointcut;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ObjectUtils;
+
+/**
+ * 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 {
+
+ public boolean matches(Method method, Class> targetClass) {
+ CacheOperationSource cas = getCacheOperationSource();
+ return (cas != null && !CollectionUtils.isEmpty(cas.getCacheOperations(method, targetClass)));
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (this == other) {
+ return true;
+ }
+ if (!(other instanceof CacheOperationSourcePointcut)) {
+ return false;
+ }
+ CacheOperationSourcePointcut otherPc = (CacheOperationSourcePointcut) other;
+ return ObjectUtils.nullSafeEquals(getCacheOperationSource(),
+ otherPc.getCacheOperationSource());
+ }
+
+ @Override
+ public int hashCode() {
+ return CacheOperationSourcePointcut.class.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getName() + ": " + getCacheOperationSource();
+ }
+
+
+ /**
+ * Obtain the underlying CacheOperationDefinitionSource (may be {@code null}).
+ * To be implemented by subclasses.
+ */
+ protected abstract CacheOperationSource getCacheOperationSource();
+
+}
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 5504fe57566..2db32e27a35 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,79 +1,79 @@
-/*
- * Copyright 2010-2011 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.cache.interceptor;
-
-import org.springframework.aop.Pointcut;
-import org.springframework.aop.framework.AbstractSingletonProxyFactoryBean;
-import org.springframework.aop.support.DefaultPointcutAdvisor;
-
-/**
- * Proxy factory bean for simplified declarative caching handling.
- * This is a convenient alternative to a standard AOP
- * {@link org.springframework.aop.framework.ProxyFactoryBean}
- * with a separate {@link CachingInterceptor} definition.
- *
- * This class is designed to facilitate declarative cache demarcation: namely, wrapping
- * a singleton target object with a caching proxy, proxying all the interfaces that the
- * target implements. Exists primarily for third-party framework integration.
- * Users should favor the {@code cache:} XML namespace
- * {@link org.springframework.cache.annotation.Cacheable @Cacheable} annotation.
- * See the declarative annotation-based caching section
- * of the Spring reference documentation for more information.
- *
- * @author Costin Leau
- * @see org.springframework.aop.framework.ProxyFactoryBean
- * @see CachingInterceptor
- */
-@SuppressWarnings("serial")
-public class CacheProxyFactoryBean extends AbstractSingletonProxyFactoryBean {
-
- private final CacheInterceptor cachingInterceptor = new CacheInterceptor();
- private Pointcut pointcut;
-
- /**
- * Set a pointcut, i.e a bean that can cause conditional invocation
- * of the CacheInterceptor depending on method and attributes passed.
- * Note: Additional interceptors are always invoked.
- * @see #setPreInterceptors
- * @see #setPostInterceptors
- */
- public void setPointcut(Pointcut pointcut) {
- this.pointcut = pointcut;
- }
-
- @Override
- protected Object createMainInterceptor() {
- this.cachingInterceptor.afterPropertiesSet();
- if (this.pointcut != null) {
- return new DefaultPointcutAdvisor(this.pointcut, this.cachingInterceptor);
- } else {
- // Rely on default pointcut.
- throw new UnsupportedOperationException();
- }
- }
-
- /**
- * Set the caching attribute source which is used to find the cache operation
- * definition.
- *
- * @param cacheDefinitionSources cache definition sources
- */
- public void setCacheDefinitionSources(CacheOperationSource... cacheDefinitionSources) {
- this.cachingInterceptor.setCacheOperationSources(cacheDefinitionSources);
- }
-
-}
+/*
+ * Copyright 2010-2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.cache.interceptor;
+
+import org.springframework.aop.Pointcut;
+import org.springframework.aop.framework.AbstractSingletonProxyFactoryBean;
+import org.springframework.aop.support.DefaultPointcutAdvisor;
+
+/**
+ * Proxy factory bean for simplified declarative caching handling.
+ * This is a convenient alternative to a standard AOP
+ * {@link org.springframework.aop.framework.ProxyFactoryBean}
+ * with a separate {@link CachingInterceptor} definition.
+ *
+ *
This class is designed to facilitate declarative cache demarcation: namely, wrapping
+ * a singleton target object with a caching proxy, proxying all the interfaces that the
+ * target implements. Exists primarily for third-party framework integration.
+ * Users should favor the {@code cache:} XML namespace
+ * {@link org.springframework.cache.annotation.Cacheable @Cacheable} annotation.
+ * See the declarative annotation-based caching section
+ * of the Spring reference documentation for more information.
+ *
+ * @author Costin Leau
+ * @see org.springframework.aop.framework.ProxyFactoryBean
+ * @see CachingInterceptor
+ */
+@SuppressWarnings("serial")
+public class CacheProxyFactoryBean extends AbstractSingletonProxyFactoryBean {
+
+ private final CacheInterceptor cachingInterceptor = new CacheInterceptor();
+ private Pointcut pointcut;
+
+ /**
+ * Set a pointcut, i.e a bean that can cause conditional invocation
+ * of the CacheInterceptor depending on method and attributes passed.
+ * Note: Additional interceptors are always invoked.
+ * @see #setPreInterceptors
+ * @see #setPostInterceptors
+ */
+ public void setPointcut(Pointcut pointcut) {
+ this.pointcut = pointcut;
+ }
+
+ @Override
+ protected Object createMainInterceptor() {
+ this.cachingInterceptor.afterPropertiesSet();
+ if (this.pointcut != null) {
+ return new DefaultPointcutAdvisor(this.pointcut, this.cachingInterceptor);
+ } else {
+ // Rely on default pointcut.
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ /**
+ * Set the caching attribute source which is used to find the cache operation
+ * definition.
+ *
+ * @param cacheDefinitionSources cache definition sources
+ */
+ public void setCacheDefinitionSources(CacheOperationSource... cacheDefinitionSources) {
+ this.cachingInterceptor.setCacheOperationSources(cacheDefinitionSources);
+ }
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java
index 5a54b72b680..edb84ba156b 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CachePutOperation.java
@@ -1,27 +1,27 @@
-/*
- * Copyright 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;
-
-/**
- * Class describing a cache 'put' operation.
- *
- * @author Costin Leau
- * @since 3.1
- */
-public class CachePutOperation extends CacheOperation {
-
-}
+/*
+ * 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.interceptor;
+
+/**
+ * Class describing a cache 'put' operation.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+public class CachePutOperation extends CacheOperation {
+
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java
index a00eeff3044..23c0b20e2c8 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/CacheableOperation.java
@@ -1,27 +1,27 @@
-/*
- * 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.interceptor;
-
-/**
- * Class describing a cache 'cacheable' operation.
- *
- * @author Costin Leau
- * @since 3.1
- */
-public class CacheableOperation extends CacheOperation {
-
-}
+/*
+ * 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.interceptor;
+
+/**
+ * Class describing a cache 'cacheable' operation.
+ *
+ * @author Costin Leau
+ * @since 3.1
+ */
+public class CacheableOperation 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 2ee5d23f4b9..3e96751a51f 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,69 +1,69 @@
-/*
- * 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.interceptor;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Collection;
-
-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[] cacheOperationSources;
-
- /**
- * Create a new CompositeCacheOperationSource for the given sources.
- * @param cacheOperationSources the CacheOperationSource instances to combine
- */
- public CompositeCacheOperationSource(CacheOperationSource... cacheOperationSources) {
- Assert.notEmpty(cacheOperationSources, "cacheOperationSources array must not be empty");
- this.cacheOperationSources = cacheOperationSources;
- }
-
- /**
- * Return the CacheOperationSource instances that this CompositeCachingDefinitionSource combines.
- */
- public final CacheOperationSource[] getCacheOperationSources() {
- return this.cacheOperationSources;
- }
-
- public Collection getCacheOperations(Method method, Class> targetClass) {
- Collection ops = null;
-
- for (CacheOperationSource source : this.cacheOperationSources) {
- Collection cacheOperations = source.getCacheOperations(method, targetClass);
- if (cacheOperations != null) {
- if (ops == null) {
- ops = new ArrayList();
- }
-
- ops.addAll(cacheOperations);
- }
- }
- return ops;
- }
-}
+/*
+ * 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.interceptor;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+
+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[] cacheOperationSources;
+
+ /**
+ * Create a new CompositeCacheOperationSource for the given sources.
+ * @param cacheOperationSources the CacheOperationSource instances to combine
+ */
+ public CompositeCacheOperationSource(CacheOperationSource... cacheOperationSources) {
+ Assert.notEmpty(cacheOperationSources, "cacheOperationSources array must not be empty");
+ this.cacheOperationSources = cacheOperationSources;
+ }
+
+ /**
+ * Return the CacheOperationSource instances that this CompositeCachingDefinitionSource combines.
+ */
+ public final CacheOperationSource[] getCacheOperationSources() {
+ return this.cacheOperationSources;
+ }
+
+ public Collection getCacheOperations(Method method, Class> targetClass) {
+ Collection ops = null;
+
+ for (CacheOperationSource source : this.cacheOperationSources) {
+ Collection cacheOperations = source.getCacheOperations(method, targetClass);
+ if (cacheOperations != null) {
+ if (ops == null) {
+ ops = new ArrayList();
+ }
+
+ ops.addAll(cacheOperations);
+ }
+ }
+ return ops;
+ }
+}
diff --git a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultKeyGenerator.java b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultKeyGenerator.java
index 55cd2a54a27..cb0dcc95d8c 100644
--- a/org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultKeyGenerator.java
+++ b/org.springframework.context/src/main/java/org/springframework/cache/interceptor/DefaultKeyGenerator.java
@@ -1,52 +1,53 @@
-/*
- * 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.interceptor;
-
-import java.lang.reflect.Method;
-
-import org.springframework.cache.interceptor.KeyGenerator;
-
-/**
- * Default key generator. Returns {@value #NO_PARAM_KEY} if no parameters are provided,
- * the parameter itself if only one is given or a hash code computed from all given
- * parameters' hash code values. Uses the constant value {@value #NULL_PARAM_KEY} for any
- * {@code null} parameters given.
- *
- * @author Costin Leau
- * @author Chris Beams
- * @since 3.1
- */
-public class DefaultKeyGenerator implements KeyGenerator {
-
- public static final int NO_PARAM_KEY = 0;
- public static final int NULL_PARAM_KEY = 53;
-
- public Object generate(Object target, Method method, Object... params) {
- if (params.length == 1) {
- return (params[0] == null ? NULL_PARAM_KEY : params[0]);
- }
- if (params.length == 0) {
- return NO_PARAM_KEY;
- }
- int hashCode = 17;
- for (Object object : params) {
- hashCode = 31 * hashCode + (object == null ? NULL_PARAM_KEY : object.hashCode());
- }
- return Integer.valueOf(hashCode);
- }
-
-}
+/*
+ * 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.interceptor;
+
+import java.lang.reflect.Method;
+
+import org.springframework.cache.interceptor.KeyGenerator;
+
+/**
+ * Default key generator. Returns {@value #NO_PARAM_KEY} if no
+ * parameters are provided, the parameter itself if only one is given or
+ * a hash code computed from all given parameters' hash code values.
+ * Uses the constant value {@value #NULL_PARAM_KEY} for any
+ * {@code null} parameters given.
+ *
+ * @author Costin Leau
+ * @author Chris Beams
+ * @since 3.1
+ */
+public class DefaultKeyGenerator implements KeyGenerator {
+
+ public static final int NO_PARAM_KEY = 0;
+ public static final int NULL_PARAM_KEY = 53;
+
+ public Object generate(Object target, Method method, Object... params) {
+ if (params.length == 1) {
+ return (params[0] == null ? NULL_PARAM_KEY : params[0]);
+ }
+ if (params.length == 0) {
+ return NO_PARAM_KEY;
+ }
+ int hashCode = 17;
+ for (Object object : params) {
+ hashCode = 31 * hashCode + (object == null ? NULL_PARAM_KEY : 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 2049ad03863..4db94bb1b07 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,81 +1,81 @@
-/*
- * 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.interceptor;
-
-import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.springframework.cache.Cache;
-import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
-import org.springframework.core.ParameterNameDiscoverer;
-import org.springframework.expression.EvaluationContext;
-import org.springframework.expression.Expression;
-import org.springframework.expression.spel.standard.SpelExpressionParser;
-
-/**
- * Utility class handling the SpEL expression parsing.
- * Meant to be used as a reusable, thread-safe component.
- *
- * 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();
-
-
- 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);
- }
-
- public boolean condition(String conditionExpression, Method method, EvaluationContext evalContext) {
- Expression condExp = this.conditionCache.get(method);
- if (condExp == null) {
- condExp = this.parser.parseExpression(conditionExpression);
- this.conditionCache.put(method, condExp);
- }
- return condExp.getValue(evalContext, boolean.class);
- }
-
- public Object key(String keyExpression, Method method, EvaluationContext evalContext) {
- Expression keyExp = this.keyCache.get(method);
- if (keyExp == null) {
- keyExp = this.parser.parseExpression(keyExpression);
- this.keyCache.put(method, keyExp);
- }
- return keyExp.getValue(evalContext);
- }
-
-}
+/*
+ * 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.interceptor;
+
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.cache.Cache;
+import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
+import org.springframework.core.ParameterNameDiscoverer;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+
+/**
+ * Utility class handling the SpEL expression parsing.
+ * Meant to be used as a reusable, thread-safe component.
+ *
+ * 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();
+
+
+ public EvaluationContext createEvaluationContext(
+ Collection