Provide common cache config
Prior to this commit, common cache operation settings had to be repeated for every operation: cache name(s), custom cache manager and custom key manager. This commit introduces the @CacheConfig annotation to bet set at class-level (either directly or as a meta-annotation). As the cache name(s) can be rationalized there, the "value" of the various annotations are no longer mandatory. CacheAnnotationParser has an API breakage to be able to retrieve information at class-level. Issue: SPR-11316
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,7 +17,6 @@
|
||||
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;
|
||||
@@ -40,6 +39,7 @@ import org.springframework.util.Assert;
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Juergen Hoeller
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
@@ -106,29 +106,40 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati
|
||||
|
||||
|
||||
@Override
|
||||
protected Collection<CacheOperation> findCacheOperations(Class<?> clazz) {
|
||||
return determineCacheOperations(clazz);
|
||||
protected Collection<CacheOperation> findCacheOperations(final Class<?> clazz) {
|
||||
return determineCacheOperations(new CacheOperationProvider() {
|
||||
@Override
|
||||
public Collection<CacheOperation> getCacheOperations(CacheAnnotationParser parser) {
|
||||
return parser.parseCacheAnnotations(clazz);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<CacheOperation> findCacheOperations(Method method) {
|
||||
return determineCacheOperations(method);
|
||||
protected Collection<CacheOperation> findCacheOperations(final Method method) {
|
||||
return determineCacheOperations(new CacheOperationProvider() {
|
||||
@Override
|
||||
public Collection<CacheOperation> getCacheOperations(CacheAnnotationParser parser) {
|
||||
return parser.parseCacheAnnotations(method);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the cache operation(s) for the given method or class.
|
||||
* Determine the cache operation(s) for the given {@link CacheOperationProvider}.
|
||||
* <p>This implementation delegates to configured
|
||||
* {@link CacheAnnotationParser}s for parsing known annotations into
|
||||
* Spring's metadata attribute class.
|
||||
* <p>Can be overridden to support custom annotations that carry
|
||||
* caching metadata.
|
||||
* @param ae the annotated method or class
|
||||
* @param provider the cache operation provider to use
|
||||
* @return the configured caching operations, or {@code null} if none found
|
||||
*/
|
||||
protected Collection<CacheOperation> determineCacheOperations(AnnotatedElement ae) {
|
||||
protected Collection<CacheOperation> determineCacheOperations(CacheOperationProvider provider) {
|
||||
Collection<CacheOperation> ops = null;
|
||||
for (CacheAnnotationParser annotationParser : this.annotationParsers) {
|
||||
Collection<CacheOperation> annOps = annotationParser.parseCacheAnnotations(ae);
|
||||
Collection<CacheOperation> annOps = provider.getCacheOperations(annotationParser);
|
||||
if (annOps != null) {
|
||||
if (ops == null) {
|
||||
ops = new ArrayList<CacheOperation>();
|
||||
@@ -166,4 +177,19 @@ public class AnnotationCacheOperationSource extends AbstractFallbackCacheOperati
|
||||
return this.annotationParsers.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback interface providing {@link CacheOperation} instance(s) based on
|
||||
* a given {@link CacheAnnotationParser}.
|
||||
*/
|
||||
protected interface CacheOperationProvider {
|
||||
|
||||
/**
|
||||
* Returns the {@link CacheOperation} instance(s) provided by the specified parser.
|
||||
*
|
||||
* @param parser the parser to use
|
||||
* @return the cache operations or {@code null} if none is found
|
||||
*/
|
||||
Collection<CacheOperation> getCacheOperations(CacheAnnotationParser parser);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
package org.springframework.cache.annotation;
|
||||
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.springframework.cache.interceptor.CacheOperation;
|
||||
@@ -28,20 +28,34 @@ import org.springframework.cache.interceptor.CacheOperation;
|
||||
* {@link Cacheable}, {@link CachePut} or {@link CacheEvict}.
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
*/
|
||||
public interface CacheAnnotationParser {
|
||||
|
||||
/**
|
||||
* Parses the cache definition for the given method or class,
|
||||
* Parses the cache definition for the given class,
|
||||
* based on a known annotation type.
|
||||
* <p>This essentially parses a known cache annotation into Spring's
|
||||
* metadata attribute class. Returns {@code null} if the method/class
|
||||
* metadata attribute class. Returns {@code null} if the class
|
||||
* is not cacheable.
|
||||
* @param ae the annotated method or class
|
||||
* @param type the annotated class
|
||||
* @return CacheOperation the configured caching operation,
|
||||
* or {@code null} if none was found
|
||||
* @see AnnotationCacheOperationSource#determineCacheOperations(AnnotatedElement)
|
||||
* @see AnnotationCacheOperationSource#findCacheOperations(Class)
|
||||
*/
|
||||
Collection<CacheOperation> parseCacheAnnotations(AnnotatedElement ae);
|
||||
Collection<CacheOperation> parseCacheAnnotations(Class<?> type);
|
||||
|
||||
/**
|
||||
* Parses the cache definition for the given method,
|
||||
* based on a known annotation type.
|
||||
* <p>This essentially parses a known cache annotation into Spring's
|
||||
* metadata attribute class. Returns {@code null} if the method
|
||||
* is not cacheable.
|
||||
* @param method the annotated method
|
||||
* @return CacheOperation the configured caching operation,
|
||||
* or {@code null} if none was found
|
||||
* @see AnnotationCacheOperationSource#findCacheOperations(Method)
|
||||
*/
|
||||
Collection<CacheOperation> parseCacheAnnotations(Method method);
|
||||
}
|
||||
|
||||
62
spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java
vendored
Normal file
62
spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Provide a way to share common cache-related settings at class-level.
|
||||
* <p>When this annotation is present on a given class, it provides a set
|
||||
* of default settings for any cache operation defined on that class.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
*/
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface CacheConfig {
|
||||
|
||||
/**
|
||||
* Name of the default caches to consider for a caching operation defined in the class.
|
||||
* <p>If none is set at the operation level, these ones are used instead of the default.
|
||||
* <p>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[] cacheNames() default {};
|
||||
|
||||
/**
|
||||
* The bean name of the default {@link org.springframework.cache.interceptor.KeyGenerator} to
|
||||
* use for the class.
|
||||
* <p>If none is set at the operation level, this one is used instead of the default.
|
||||
* <p>The key generator is mutually exclusive with the use of a custom key. When such key is
|
||||
* defined for the operation, the value of this key generator is ignored.
|
||||
*/
|
||||
String keyGenerator() default "";
|
||||
|
||||
/**
|
||||
* The bean name of the custom {@link org.springframework.cache.CacheManager} to use.
|
||||
* <p>If none is set at the operation level, this one is used instead of the default.
|
||||
*/
|
||||
String cacheManager() default "";
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ import java.lang.annotation.Target;
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
* @see CacheConfig
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -42,7 +43,7 @@ public @interface CacheEvict {
|
||||
* <p>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();
|
||||
String[] value() default {};
|
||||
|
||||
/**
|
||||
* Spring Expression Language (SpEL) attribute for computing the key dynamically.
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.cache.Cache;
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
* @see CacheConfig
|
||||
*/
|
||||
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -47,7 +48,7 @@ public @interface CachePut {
|
||||
* <p>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();
|
||||
String[] value() default {};
|
||||
|
||||
/**
|
||||
* Spring Expression Language (SpEL) attribute for computing the key dynamically.
|
||||
|
||||
@@ -33,6 +33,7 @@ import java.lang.annotation.Target;
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
* @since 3.1
|
||||
* @see CacheConfig
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -45,7 +46,7 @@ public @interface Cacheable {
|
||||
* <p>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();
|
||||
String[] value() default {};
|
||||
|
||||
/**
|
||||
* Spring Expression Language (SpEL) attribute for computing the key dynamically.
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.springframework.cache.annotation;
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
@@ -26,6 +27,7 @@ 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;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -44,35 +46,47 @@ import org.springframework.util.StringUtils;
|
||||
public class SpringCacheAnnotationParser implements CacheAnnotationParser, Serializable {
|
||||
|
||||
@Override
|
||||
public Collection<CacheOperation> parseCacheAnnotations(AnnotatedElement ae) {
|
||||
public Collection<CacheOperation> parseCacheAnnotations(Class<?> type) {
|
||||
DefaultCacheConfig defaultConfig = getDefaultCacheConfig(type);
|
||||
return parseCacheAnnotations(defaultConfig, type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<CacheOperation> parseCacheAnnotations(Method method) {
|
||||
DefaultCacheConfig defaultConfig = getDefaultCacheConfig(method.getDeclaringClass());
|
||||
return parseCacheAnnotations(defaultConfig, method);
|
||||
}
|
||||
|
||||
protected Collection<CacheOperation> parseCacheAnnotations(DefaultCacheConfig cachingConfig,
|
||||
AnnotatedElement ae) {
|
||||
Collection<CacheOperation> ops = null;
|
||||
|
||||
Collection<Cacheable> cacheables = getAnnotations(ae, Cacheable.class);
|
||||
if (cacheables != null) {
|
||||
ops = lazyInit(ops);
|
||||
for (Cacheable cacheable : cacheables) {
|
||||
ops.add(parseCacheableAnnotation(ae, cacheable));
|
||||
ops.add(parseCacheableAnnotation(ae, cachingConfig, cacheable));
|
||||
}
|
||||
}
|
||||
Collection<CacheEvict> evicts = getAnnotations(ae, CacheEvict.class);
|
||||
if (evicts != null) {
|
||||
ops = lazyInit(ops);
|
||||
for (CacheEvict e : evicts) {
|
||||
ops.add(parseEvictAnnotation(ae, e));
|
||||
ops.add(parseEvictAnnotation(ae, cachingConfig, e));
|
||||
}
|
||||
}
|
||||
Collection<CachePut> updates = getAnnotations(ae, CachePut.class);
|
||||
if (updates != null) {
|
||||
ops = lazyInit(ops);
|
||||
for (CachePut p : updates) {
|
||||
ops.add(parseUpdateAnnotation(ae, p));
|
||||
ops.add(parseUpdateAnnotation(ae, cachingConfig, p));
|
||||
}
|
||||
}
|
||||
Collection<Caching> caching = getAnnotations(ae, Caching.class);
|
||||
if (caching != null) {
|
||||
ops = lazyInit(ops);
|
||||
for (Caching c : caching) {
|
||||
ops.addAll(parseCachingAnnotation(ae, c));
|
||||
ops.addAll(parseCachingAnnotation(ae, cachingConfig, c));
|
||||
}
|
||||
}
|
||||
return ops;
|
||||
@@ -82,7 +96,8 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
return (ops != null ? ops : new ArrayList<CacheOperation>(1));
|
||||
}
|
||||
|
||||
CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, Cacheable caching) {
|
||||
CacheableOperation parseCacheableAnnotation(AnnotatedElement ae,
|
||||
DefaultCacheConfig defaultConfig, Cacheable caching) {
|
||||
CacheableOperation cuo = new CacheableOperation();
|
||||
cuo.setCacheNames(caching.value());
|
||||
cuo.setCondition(caching.condition());
|
||||
@@ -92,11 +107,14 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
cuo.setCacheManager(caching.cacheManager());
|
||||
cuo.setName(ae.toString());
|
||||
|
||||
checkKeySourceConsistency(ae, caching.key(), caching.keyGenerator());
|
||||
defaultConfig.applyDefault(cuo);
|
||||
|
||||
validateCacheOperation(ae, cuo);
|
||||
return cuo;
|
||||
}
|
||||
|
||||
CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, CacheEvict caching) {
|
||||
CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae,
|
||||
DefaultCacheConfig defaultConfig, CacheEvict caching) {
|
||||
CacheEvictOperation ceo = new CacheEvictOperation();
|
||||
ceo.setCacheNames(caching.value());
|
||||
ceo.setCondition(caching.condition());
|
||||
@@ -107,11 +125,14 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
ceo.setBeforeInvocation(caching.beforeInvocation());
|
||||
ceo.setName(ae.toString());
|
||||
|
||||
checkKeySourceConsistency(ae, caching.key(), caching.keyGenerator());
|
||||
defaultConfig.applyDefault(ceo);
|
||||
|
||||
validateCacheOperation(ae, ceo);
|
||||
return ceo;
|
||||
}
|
||||
|
||||
CacheOperation parseUpdateAnnotation(AnnotatedElement ae, CachePut caching) {
|
||||
CacheOperation parseUpdateAnnotation(AnnotatedElement ae,
|
||||
DefaultCacheConfig defaultConfig, CachePut caching) {
|
||||
CachePutOperation cuo = new CachePutOperation();
|
||||
cuo.setCacheNames(caching.value());
|
||||
cuo.setCondition(caching.condition());
|
||||
@@ -121,38 +142,56 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
cuo.setCacheManager(caching.cacheManager());
|
||||
cuo.setName(ae.toString());
|
||||
|
||||
checkKeySourceConsistency(ae, caching.key(), caching.keyGenerator());
|
||||
defaultConfig.applyDefault(cuo);
|
||||
|
||||
validateCacheOperation(ae, cuo);
|
||||
return cuo;
|
||||
}
|
||||
|
||||
Collection<CacheOperation> parseCachingAnnotation(AnnotatedElement ae, Caching caching) {
|
||||
Collection<CacheOperation> parseCachingAnnotation(AnnotatedElement ae,
|
||||
DefaultCacheConfig defaultConfig, Caching caching) {
|
||||
Collection<CacheOperation> ops = null;
|
||||
|
||||
Cacheable[] cacheables = caching.cacheable();
|
||||
if (!ObjectUtils.isEmpty(cacheables)) {
|
||||
ops = lazyInit(ops);
|
||||
for (Cacheable cacheable : cacheables) {
|
||||
ops.add(parseCacheableAnnotation(ae, cacheable));
|
||||
ops.add(parseCacheableAnnotation(ae, defaultConfig, cacheable));
|
||||
}
|
||||
}
|
||||
CacheEvict[] evicts = caching.evict();
|
||||
if (!ObjectUtils.isEmpty(evicts)) {
|
||||
ops = lazyInit(ops);
|
||||
for (CacheEvict evict : evicts) {
|
||||
ops.add(parseEvictAnnotation(ae, evict));
|
||||
ops.add(parseEvictAnnotation(ae, defaultConfig, evict));
|
||||
}
|
||||
}
|
||||
CachePut[] updates = caching.put();
|
||||
if (!ObjectUtils.isEmpty(updates)) {
|
||||
ops = lazyInit(ops);
|
||||
for (CachePut update : updates) {
|
||||
ops.add(parseUpdateAnnotation(ae, update));
|
||||
ops.add(parseUpdateAnnotation(ae, defaultConfig, update));
|
||||
}
|
||||
}
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the {@link DefaultCacheConfig} instance for the specified {@link Class}.
|
||||
*
|
||||
* @param target the class-level to handle
|
||||
* @return the default config (never {@code null})
|
||||
*/
|
||||
DefaultCacheConfig getDefaultCacheConfig(Class<?> target) {
|
||||
final CacheConfig annotation = AnnotationUtils.getAnnotation(target, CacheConfig.class);
|
||||
if (annotation != null) {
|
||||
return new DefaultCacheConfig(annotation.cacheManager(),
|
||||
annotation.keyGenerator(), annotation.cacheNames());
|
||||
}
|
||||
return new DefaultCacheConfig();
|
||||
}
|
||||
|
||||
private <T extends Annotation> Collection<T> getAnnotations(AnnotatedElement ae, Class<T> annotationType) {
|
||||
Collection<T> anns = new ArrayList<T>(2);
|
||||
|
||||
@@ -173,13 +212,27 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
return (anns.isEmpty() ? null : anns);
|
||||
}
|
||||
|
||||
private void checkKeySourceConsistency(AnnotatedElement ae, String key, String keyGenerator) {
|
||||
if (StringUtils.hasText(key) && StringUtils.hasText(keyGenerator)) {
|
||||
/**
|
||||
* Validates the specified {@link CacheOperation}.
|
||||
* <p>Throws an {@link IllegalStateException} if the state of the operation is
|
||||
* invalid. As there might be multiple sources for default values, this ensure
|
||||
* that the operation is in a proper state before being returned.
|
||||
*
|
||||
* @param ae the annotated element of the cache operation
|
||||
* @param operation the {@link CacheOperation} to validate
|
||||
*/
|
||||
private void validateCacheOperation(AnnotatedElement ae, CacheOperation operation) {
|
||||
if (StringUtils.hasText(operation.getKey()) && StringUtils.hasText(operation.getKeyGenerator())) {
|
||||
throw new IllegalStateException("Invalid cache annotation configuration on '"
|
||||
+ ae.toString() + "'. Both 'key' and 'keyGenerator' attributes have been set. " +
|
||||
"These attributes are mutually exclusive: either set the SpEL expression used to" +
|
||||
"compute the key at runtime or set the name of the KeyGenerator bean to use.");
|
||||
}
|
||||
if (operation.getCacheNames().isEmpty()) {
|
||||
throw new IllegalStateException("No cache names could be detected on '"
|
||||
+ ae.toString()+ "'. Make sure to set the value parameter on the annotation or" +
|
||||
"declare a @CacheConfig at the class-level with the default cache name(s) to use.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -192,4 +245,41 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
|
||||
return SpringCacheAnnotationParser.class.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides default settings for a given set of cache operations.
|
||||
*/
|
||||
static class DefaultCacheConfig {
|
||||
private final String cacheManager;
|
||||
private final String keyGenerator;
|
||||
private final String[] cacheNames;
|
||||
|
||||
private DefaultCacheConfig(String cacheManager, String keyGenerator, String[] cacheNames) {
|
||||
this.cacheManager = cacheManager;
|
||||
this.keyGenerator = keyGenerator;
|
||||
this.cacheNames = cacheNames;
|
||||
}
|
||||
|
||||
public DefaultCacheConfig() {
|
||||
this(null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply the defaults to the specified {@link CacheOperation}.
|
||||
*
|
||||
* @param operation the operation to update
|
||||
*/
|
||||
public void applyDefault(CacheOperation operation) {
|
||||
if (!StringUtils.hasText(operation.getCacheManager()) && StringUtils.hasText(cacheManager)) {
|
||||
operation.setCacheManager(cacheManager);
|
||||
}
|
||||
if (!StringUtils.hasText(operation.getKey()) && !StringUtils.hasText(operation.getKeyGenerator())
|
||||
&& StringUtils.hasText(keyGenerator)) {
|
||||
operation.setKeyGenerator(keyGenerator);
|
||||
}
|
||||
if (operation.getCacheNames().isEmpty() && cacheNames != null) {
|
||||
operation.setCacheNames(cacheNames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -73,10 +73,10 @@ public abstract class CacheOperation {
|
||||
}
|
||||
|
||||
public void setCacheNames(String[] cacheNames) {
|
||||
Assert.notEmpty(cacheNames);
|
||||
this.cacheNames = new LinkedHashSet<String>(cacheNames.length);
|
||||
for (String string : cacheNames) {
|
||||
this.cacheNames.add(string);
|
||||
for (String cacheName : cacheNames) {
|
||||
Assert.hasText(cacheName, "Cache name must be set if specified.");
|
||||
this.cacheNames.add(cacheName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user