Introduce alias for 'value' attribute in caching annotations

This commit introduces new 'cacheNames' attributes (analogous to the
existing attribute of the same name in @CacheConfig) as aliases for the
'value' attributes in @Cacheable, @CachePut, and @CacheEvict.

In addition, SpringCacheAnnotationParser.getAnnotations() has been
refactored to support synthesized annotations.

Issue: SPR-11393
This commit is contained in:
Sam Brannen 2015-05-31 22:51:37 +02:00
parent de06f422f3
commit 4dffeeee64
10 changed files with 172 additions and 134 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -60,71 +60,71 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
} }
@Override @Override
@CacheEvict(value = "testCache", allEntries = true) @CacheEvict(cacheNames = "testCache", allEntries = true)
public void evictAll(Object arg1) { public void evictAll(Object arg1) {
} }
@Override @Override
@CacheEvict(value = "testCache", beforeInvocation = true) @CacheEvict(cacheNames = "testCache", beforeInvocation = true)
public void evictEarly(Object arg1) { public void evictEarly(Object arg1) {
throw new RuntimeException("exception thrown - evict should still occur"); throw new RuntimeException("exception thrown - evict should still occur");
} }
@Override @Override
@CacheEvict(value = "testCache", key = "#p0") @CacheEvict(cacheNames = "testCache", key = "#p0")
public void evict(Object arg1, Object arg2) { public void evict(Object arg1, Object arg2) {
} }
@Override @Override
@CacheEvict(value = "testCache", key = "#p0", beforeInvocation = true) @CacheEvict(cacheNames = "testCache", key = "#p0", beforeInvocation = true)
public void invalidateEarly(Object arg1, Object arg2) { public void invalidateEarly(Object arg1, Object arg2) {
throw new RuntimeException("exception thrown - evict should still occur"); throw new RuntimeException("exception thrown - evict should still occur");
} }
@Override @Override
@Cacheable(value = "testCache", key = "#p0") @Cacheable(cacheNames = "testCache", key = "#p0")
public Object key(Object arg1, Object arg2) { public Object key(Object arg1, Object arg2) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache") @Cacheable("testCache")
public Object varArgsKey(Object... args) { public Object varArgsKey(Object... args) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", key = "#root.methodName + #root.caches[0].name") @Cacheable(cacheNames = "testCache", key = "#root.methodName + #root.caches[0].name")
public Object name(Object arg1) { public Object name(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") @Cacheable(cacheNames = "testCache", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
public Object rootVars(Object arg1) { public Object rootVars(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", keyGenerator = "customKyeGenerator") @Cacheable(cacheNames = "testCache", keyGenerator = "customKyeGenerator")
public Object customKeyGenerator(Object arg1) { public Object customKeyGenerator(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", keyGenerator = "unknownBeanName") @Cacheable(cacheNames = "testCache", keyGenerator = "unknownBeanName")
public Object unknownCustomKeyGenerator(Object arg1) { public Object unknownCustomKeyGenerator(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", cacheManager = "customCacheManager") @Cacheable(cacheNames = "testCache", cacheManager = "customCacheManager")
public Object customCacheManager(Object arg1) { public Object customCacheManager(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", cacheManager = "unknownBeanName") @Cacheable(cacheNames = "testCache", cacheManager = "unknownBeanName")
public Object unknownCustomCacheManager(Object arg1) { public Object unknownCustomCacheManager(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@ -136,7 +136,7 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
} }
@Override @Override
@CachePut(value = "testCache", condition = "#arg.equals(3)") @CachePut(cacheNames = "testCache", condition = "#arg.equals(3)")
public Object conditionalUpdate(Object arg) { public Object conditionalUpdate(Object arg) {
return arg; return arg;
} }
@ -171,19 +171,19 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
} }
@Override @Override
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") }) @Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#p0") })
public Object multiEvict(Object arg1) { public Object multiEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) @Caching(cacheable = { @Cacheable(cacheNames = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
public Object multiCacheAndEvict(Object arg1) { public Object multiCacheAndEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) @Caching(cacheable = { @Cacheable(cacheNames = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
public Object multiConditionalCacheAndEvict(Object arg1) { public Object multiConditionalCacheAndEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@ -195,7 +195,7 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
} }
@Override @Override
@CachePut(value="primary", key="#result.id") @CachePut(cacheNames = "primary", key = "#result.id")
public TestEntity putRefersToResult(TestEntity arg1) { public TestEntity putRefersToResult(TestEntity arg1) {
arg1.setId(Long.MIN_VALUE); arg1.setId(Long.MIN_VALUE);
return arg1; return arg1;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -52,83 +52,83 @@ public class DefaultCacheableService implements CacheableService<Long> {
} }
@Override @Override
@CacheEvict(value = "testCache", allEntries = true) @CacheEvict(cacheNames = "testCache", allEntries = true)
public void evictAll(Object arg1) { public void evictAll(Object arg1) {
} }
@Override @Override
@CacheEvict(value = "testCache", beforeInvocation = true) @CacheEvict(cacheNames = "testCache", beforeInvocation = true)
public void evictEarly(Object arg1) { public void evictEarly(Object arg1) {
throw new RuntimeException("exception thrown - evict should still occur"); throw new RuntimeException("exception thrown - evict should still occur");
} }
@Override @Override
@CacheEvict(value = "testCache", key = "#p0") @CacheEvict(cacheNames = "testCache", key = "#p0")
public void evict(Object arg1, Object arg2) { public void evict(Object arg1, Object arg2) {
} }
@Override @Override
@CacheEvict(value = "testCache", key = "#p0", beforeInvocation = true) @CacheEvict(cacheNames = "testCache", key = "#p0", beforeInvocation = true)
public void invalidateEarly(Object arg1, Object arg2) { public void invalidateEarly(Object arg1, Object arg2) {
throw new RuntimeException("exception thrown - evict should still occur"); throw new RuntimeException("exception thrown - evict should still occur");
} }
@Override @Override
@Cacheable(value = "testCache", condition = "#classField == 3") @Cacheable(cacheNames = "testCache", condition = "#classField == 3")
public Long conditional(int classField) { public Long conditional(int classField) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", unless = "#result > 10") @Cacheable(cacheNames = "testCache", unless = "#result > 10")
public Long unless(int arg) { public Long unless(int arg) {
return (long) arg; return (long) arg;
} }
@Override @Override
@Cacheable(value = "testCache", key = "#p0") @Cacheable(cacheNames = "testCache", key = "#p0")
public Long key(Object arg1, Object arg2) { public Long key(Object arg1, Object arg2) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache") @Cacheable("testCache")
public Long varArgsKey(Object... args) { public Long varArgsKey(Object... args) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", key = "#root.methodName") @Cacheable(cacheNames = "testCache", key = "#root.methodName")
public Long name(Object arg1) { public Long name(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") @Cacheable(cacheNames = "testCache", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
public Long rootVars(Object arg1) { public Long rootVars(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", keyGenerator = "customKeyGenerator") @Cacheable(cacheNames = "testCache", keyGenerator = "customKeyGenerator")
public Long customKeyGenerator(Object arg1) { public Long customKeyGenerator(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", keyGenerator = "unknownBeanName") @Cacheable(cacheNames = "testCache", keyGenerator = "unknownBeanName")
public Long unknownCustomKeyGenerator(Object arg1) { public Long unknownCustomKeyGenerator(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", cacheManager = "customCacheManager") @Cacheable(cacheNames = "testCache", cacheManager = "customCacheManager")
public Long customCacheManager(Object arg1) { public Long customCacheManager(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", cacheManager = "unknownBeanName") @Cacheable(cacheNames = "testCache", cacheManager = "unknownBeanName")
public Long unknownCustomCacheManager(Object arg1) { public Long unknownCustomCacheManager(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@ -140,7 +140,7 @@ public class DefaultCacheableService implements CacheableService<Long> {
} }
@Override @Override
@CachePut(value = "testCache", condition = "#arg.equals(3)") @CachePut(cacheNames = "testCache", condition = "#arg.equals(3)")
public Long conditionalUpdate(Object arg) { public Long conditionalUpdate(Object arg) {
return Long.valueOf(arg.toString()); return Long.valueOf(arg.toString());
} }
@ -178,20 +178,20 @@ public class DefaultCacheableService implements CacheableService<Long> {
} }
@Override @Override
//FIXME @Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0"), @CacheEvict(value = "primary", key = "#p0 + 'A'") }) //FIXME @Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#p0"), @CacheEvict(cacheNames = "primary", key = "#p0 + 'A'") })
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") }) @Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#p0") })
public Long multiEvict(Object arg1) { public Long multiEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) @Caching(cacheable = { @Cacheable(cacheNames = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
public Long multiCacheAndEvict(Object arg1) { public Long multiCacheAndEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) @Caching(cacheable = { @Cacheable(cacheNames = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
public Long multiConditionalCacheAndEvict(Object arg1) { public Long multiConditionalCacheAndEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@ -203,7 +203,7 @@ public class DefaultCacheableService implements CacheableService<Long> {
} }
@Override @Override
@CachePut(value="primary", key="#result.id") @CachePut(cacheNames = "primary", key = "#result.id")
public TestEntity putRefersToResult(TestEntity arg1) { public TestEntity putRefersToResult(TestEntity arg1) {
arg1.setId(Long.MIN_VALUE); arg1.setId(Long.MIN_VALUE);
return arg1; return arg1;

View File

@ -23,6 +23,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/** /**
* Annotation indicating that a method (or all methods on a class) triggers * Annotation indicating that a method (or all methods on a class) triggers
* a cache eviction operation. * a cache eviction operation.
@ -39,12 +41,22 @@ import java.lang.annotation.Target;
@Documented @Documented
public @interface CacheEvict { public @interface CacheEvict {
/**
* Alias for {@link #cacheNames}.
*/
@AliasFor(attribute = "cacheNames")
String[] value() default {};
/** /**
* Names of the caches to use for the cache eviction operation. * Names of the caches to use for the cache eviction operation.
* <p>Names may be used to determine the target cache (or caches), matching * <p>Names may be used to determine the target cache (or caches), matching
* the qualifier value or bean name of a specific bean definition. * the qualifier value or bean name of a specific bean definition.
* @since 4.2
* @see #value
* @see CacheConfig#cacheNames
*/ */
String[] value() default {}; @AliasFor(attribute = "value")
String[] cacheNames() default {};
/** /**
* Spring Expression Language (SpEL) expression for computing the key dynamically. * Spring Expression Language (SpEL) expression for computing the key dynamically.

View File

@ -24,6 +24,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.core.annotation.AliasFor;
/** /**
* Annotation indicating that a method (or all methods on a class) triggers * Annotation indicating that a method (or all methods on a class) triggers
@ -46,12 +47,22 @@ import org.springframework.cache.Cache;
@Documented @Documented
public @interface CachePut { public @interface CachePut {
/**
* Alias for {@link #cacheNames}.
*/
@AliasFor(attribute = "cacheNames")
String[] value() default {};
/** /**
* Names of the caches to use for the cache put operation. * Names of the caches to use for the cache put operation.
* <p>Names may be used to determine the target cache (or caches), matching * <p>Names may be used to determine the target cache (or caches), matching
* the qualifier value or bean name of a specific bean definition. * the qualifier value or bean name of a specific bean definition.
* @since 4.2
* @see #value
* @see CacheConfig#cacheNames
*/ */
String[] value() default {}; @AliasFor(attribute = "value")
String[] cacheNames() default {};
/** /**
* Spring Expression Language (SpEL) expression for computing the key dynamically. * Spring Expression Language (SpEL) expression for computing the key dynamically.

View File

@ -23,6 +23,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/** /**
* Annotation indicating that the result of invoking a method (or all methods * Annotation indicating that the result of invoking a method (or all methods
* in a class) can be cached. * in a class) can be cached.
@ -50,12 +52,22 @@ import java.lang.annotation.Target;
@Documented @Documented
public @interface Cacheable { public @interface Cacheable {
/**
* Alias for {@link #cacheNames}.
*/
@AliasFor(attribute = "cacheNames")
String[] value() default {};
/** /**
* Names of the caches in which method invocation results are stored. * Names of the caches in which method invocation results are stored.
* <p>Names may be used to determine the target cache (or caches), matching * <p>Names may be used to determine the target cache (or caches), matching
* the qualifier value or bean name of a specific bean definition. * the qualifier value or bean name of a specific bean definition.
* @since 4.2
* @see #value
* @see CacheConfig#cacheNames
*/ */
String[] value() default {}; @AliasFor(attribute = "value")
String[] cacheNames() default {};
/** /**
* Spring Expression Language (SpEL) expression for computing the key dynamically. * Spring Expression Language (SpEL) expression for computing the key dynamically.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -33,13 +33,14 @@ import org.springframework.util.StringUtils;
/** /**
* Strategy implementation for parsing Spring's {@link Caching}, {@link Cacheable}, * Strategy implementation for parsing Spring's {@link Caching}, {@link Cacheable},
* {@link CacheEvict} and {@link CachePut} annotations. * {@link CacheEvict}, and {@link CachePut} annotations.
* *
* @author Costin Leau * @author Costin Leau
* @author Juergen Hoeller * @author Juergen Hoeller
* @author Chris Beams * @author Chris Beams
* @author Phillip Webb * @author Phillip Webb
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Sam Brannen
* @since 3.1 * @since 3.1
*/ */
@SuppressWarnings("serial") @SuppressWarnings("serial")
@ -96,16 +97,16 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
return (ops != null ? ops : new ArrayList<CacheOperation>(1)); return (ops != null ? ops : new ArrayList<CacheOperation>(1));
} }
CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, Cacheable caching) { CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, Cacheable cacheable) {
CacheableOperation op = new CacheableOperation(); CacheableOperation op = new CacheableOperation();
op.setCacheNames(caching.value()); op.setCacheNames(cacheable.cacheNames());
op.setCondition(caching.condition()); op.setCondition(cacheable.condition());
op.setUnless(caching.unless()); op.setUnless(cacheable.unless());
op.setKey(caching.key()); op.setKey(cacheable.key());
op.setKeyGenerator(caching.keyGenerator()); op.setKeyGenerator(cacheable.keyGenerator());
op.setCacheManager(caching.cacheManager()); op.setCacheManager(cacheable.cacheManager());
op.setCacheResolver(caching.cacheResolver()); op.setCacheResolver(cacheable.cacheResolver());
op.setName(ae.toString()); op.setName(ae.toString());
defaultConfig.applyDefault(op); defaultConfig.applyDefault(op);
@ -114,17 +115,17 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
return op; return op;
} }
CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, CacheEvict caching) { CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, CacheEvict cacheEvict) {
CacheEvictOperation op = new CacheEvictOperation(); CacheEvictOperation op = new CacheEvictOperation();
op.setCacheNames(caching.value()); op.setCacheNames(cacheEvict.cacheNames());
op.setCondition(caching.condition()); op.setCondition(cacheEvict.condition());
op.setKey(caching.key()); op.setKey(cacheEvict.key());
op.setKeyGenerator(caching.keyGenerator()); op.setKeyGenerator(cacheEvict.keyGenerator());
op.setCacheManager(caching.cacheManager()); op.setCacheManager(cacheEvict.cacheManager());
op.setCacheResolver(caching.cacheResolver()); op.setCacheResolver(cacheEvict.cacheResolver());
op.setCacheWide(caching.allEntries()); op.setCacheWide(cacheEvict.allEntries());
op.setBeforeInvocation(caching.beforeInvocation()); op.setBeforeInvocation(cacheEvict.beforeInvocation());
op.setName(ae.toString()); op.setName(ae.toString());
defaultConfig.applyDefault(op); defaultConfig.applyDefault(op);
@ -133,16 +134,16 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
return op; return op;
} }
CacheOperation parsePutAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, CachePut caching) { CacheOperation parsePutAnnotation(AnnotatedElement ae, DefaultCacheConfig defaultConfig, CachePut cachePut) {
CachePutOperation op = new CachePutOperation(); CachePutOperation op = new CachePutOperation();
op.setCacheNames(caching.value()); op.setCacheNames(cachePut.cacheNames());
op.setCondition(caching.condition()); op.setCondition(cachePut.condition());
op.setUnless(caching.unless()); op.setUnless(cachePut.unless());
op.setKey(caching.key()); op.setKey(cachePut.key());
op.setKeyGenerator(caching.keyGenerator()); op.setKeyGenerator(cachePut.keyGenerator());
op.setCacheManager(caching.cacheManager()); op.setCacheManager(cachePut.cacheManager());
op.setCacheResolver(caching.cacheResolver()); op.setCacheResolver(cachePut.cacheResolver());
op.setName(ae.toString()); op.setName(ae.toString());
defaultConfig.applyDefault(op); defaultConfig.applyDefault(op);
@ -161,18 +162,18 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
ops.add(parseCacheableAnnotation(ae, defaultConfig, cacheable)); ops.add(parseCacheableAnnotation(ae, defaultConfig, cacheable));
} }
} }
CacheEvict[] evicts = caching.evict(); CacheEvict[] cacheEvicts = caching.evict();
if (!ObjectUtils.isEmpty(evicts)) { if (!ObjectUtils.isEmpty(cacheEvicts)) {
ops = lazyInit(ops); ops = lazyInit(ops);
for (CacheEvict evict : evicts) { for (CacheEvict cacheEvict : cacheEvicts) {
ops.add(parseEvictAnnotation(ae, defaultConfig, evict)); ops.add(parseEvictAnnotation(ae, defaultConfig, cacheEvict));
} }
} }
CachePut[] updates = caching.put(); CachePut[] cachePuts = caching.put();
if (!ObjectUtils.isEmpty(updates)) { if (!ObjectUtils.isEmpty(cachePuts)) {
ops = lazyInit(ops); ops = lazyInit(ops);
for (CachePut update : updates) { for (CachePut cachePut : cachePuts) {
ops.add(parsePutAnnotation(ae, defaultConfig, update)); ops.add(parsePutAnnotation(ae, defaultConfig, cachePut));
} }
} }
@ -199,14 +200,14 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
// look at raw annotation // look at raw annotation
T ann = ae.getAnnotation(annotationType); T ann = ae.getAnnotation(annotationType);
if (ann != null) { if (ann != null) {
anns.add(ann); anns.add(AnnotationUtils.synthesizeAnnotation(ann, ae));
} }
// scan meta-annotations // scan meta-annotations
for (Annotation metaAnn : ae.getAnnotations()) { for (Annotation metaAnn : ae.getAnnotations()) {
ann = metaAnn.annotationType().getAnnotation(annotationType); ann = metaAnn.annotationType().getAnnotation(annotationType);
if (ann != null) { if (ann != null) {
anns.add(ann); anns.add(AnnotationUtils.synthesizeAnnotation(ann, ae));
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.junit.Test; import org.junit.Test;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Cacheable;
@ -140,8 +141,8 @@ public class CacheReproTests {
@Override @Override
@Caching(cacheable = { @Caching(cacheable = {
@Cacheable(value = "bigCache", unless = "#result.size() < 4"), @Cacheable(cacheNames = "bigCache", unless = "#result.size() < 4"),
@Cacheable(value = "smallCache", unless = "#result.size() > 3") }) @Cacheable(cacheNames = "smallCache", unless = "#result.size() > 3") })
public List<String> multiple(int id) { public List<String> multiple(int id) {
if (this.multipleCount > 0) { if (this.multipleCount > 0) {
fail("Called too many times"); fail("Called too many times");
@ -208,7 +209,7 @@ public class CacheReproTests {
return new Object(); return new Object();
} }
@Cacheable(value = "cache", condition = "false") @Cacheable(cacheNames = "cache", condition = "false")
public Object getNeverCache(String key) { public Object getNeverCache(String key) {
return new Object(); return new Object();
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -257,15 +257,15 @@ public class AnnotationCacheOperationSourceTests {
public void caching() { public void caching() {
} }
@Cacheable(value = "test", keyGenerator = "custom") @Cacheable(cacheNames = "test", keyGenerator = "custom")
public void customKeyGenerator() { public void customKeyGenerator() {
} }
@Cacheable(value = "test", cacheManager = "custom") @Cacheable(cacheNames = "test", cacheManager = "custom")
public void customCacheManager() { public void customCacheManager() {
} }
@Cacheable(value = "test", cacheResolver = "custom") @Cacheable(cacheNames = "test", cacheResolver = "custom")
public void customCacheResolver() { public void customCacheResolver() {
} }
@ -279,7 +279,7 @@ public class AnnotationCacheOperationSourceTests {
public void multipleStereotype() { public void multipleStereotype() {
} }
@Caching(cacheable = {@Cacheable(value = "test", key = "a"), @Cacheable(value = "test", key = "b")}) @Caching(cacheable = { @Cacheable(cacheNames = "test", key = "a"), @Cacheable(cacheNames = "test", key = "b") })
public void multipleCaching() { public void multipleCaching() {
} }
@ -287,7 +287,7 @@ public class AnnotationCacheOperationSourceTests {
public void customKeyGeneratorInherited() { public void customKeyGeneratorInherited() {
} }
@Cacheable(value = "test", key = "#root.methodName", keyGenerator = "custom") @Cacheable(cacheNames = "test", key = "#root.methodName", keyGenerator = "custom")
public void invalidKeyAndKeyGeneratorSet() { public void invalidKeyAndKeyGeneratorSet() {
} }
@ -299,7 +299,7 @@ public class AnnotationCacheOperationSourceTests {
public void customCacheResolverInherited() { public void customCacheResolverInherited() {
} }
@Cacheable(value = "test", cacheManager = "custom", cacheResolver = "custom") @Cacheable(cacheNames = "test", cacheManager = "custom", cacheResolver = "custom")
public void invalidCacheResolverAndCacheManagerSet() { public void invalidCacheResolverAndCacheManagerSet() {
} }
@ -374,31 +374,31 @@ public class AnnotationCacheOperationSourceTests {
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Cacheable(value = "foo", keyGenerator = "custom") @Cacheable(cacheNames = "foo", keyGenerator = "custom")
public @interface CacheableFooCustomKeyGenerator { public @interface CacheableFooCustomKeyGenerator {
} }
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Cacheable(value = "foo", cacheManager = "custom") @Cacheable(cacheNames = "foo", cacheManager = "custom")
public @interface CacheableFooCustomCacheManager { public @interface CacheableFooCustomCacheManager {
} }
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Cacheable(value = "foo", cacheResolver = "custom") @Cacheable(cacheNames = "foo", cacheResolver = "custom")
public @interface CacheableFooCustomCacheResolver { public @interface CacheableFooCustomCacheResolver {
} }
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@CacheEvict(value = "foo") @CacheEvict("foo")
public @interface EvictFoo { public @interface EvictFoo {
} }
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@CacheEvict(value = "bar") @CacheEvict("bar")
public @interface EvictBar { public @interface EvictBar {
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -46,7 +46,7 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
} }
@Override @Override
@Cacheable(value = "testCache", unless = "#result > 10") @Cacheable(cacheNames = "testCache", unless = "#result > 10")
public Object unless(int arg) { public Object unless(int arg) {
return arg; return arg;
} }
@ -63,71 +63,71 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
} }
@Override @Override
@CacheEvict(value = "testCache", allEntries = true) @CacheEvict(cacheNames = "testCache", allEntries = true)
public void evictAll(Object arg1) { public void evictAll(Object arg1) {
} }
@Override @Override
@CacheEvict(value = "testCache", beforeInvocation = true) @CacheEvict(cacheNames = "testCache", beforeInvocation = true)
public void evictEarly(Object arg1) { public void evictEarly(Object arg1) {
throw new RuntimeException("exception thrown - evict should still occur"); throw new RuntimeException("exception thrown - evict should still occur");
} }
@Override @Override
@CacheEvict(value = "testCache", key = "#p0") @CacheEvict(cacheNames = "testCache", key = "#p0")
public void evict(Object arg1, Object arg2) { public void evict(Object arg1, Object arg2) {
} }
@Override @Override
@CacheEvict(value = "testCache", key = "#p0", beforeInvocation = true) @CacheEvict(cacheNames = "testCache", key = "#p0", beforeInvocation = true)
public void invalidateEarly(Object arg1, Object arg2) { public void invalidateEarly(Object arg1, Object arg2) {
throw new RuntimeException("exception thrown - evict should still occur"); throw new RuntimeException("exception thrown - evict should still occur");
} }
@Override @Override
@Cacheable(value = "testCache", key = "#p0") @Cacheable(cacheNames = "testCache", key = "#p0")
public Object key(Object arg1, Object arg2) { public Object key(Object arg1, Object arg2) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache") @Cacheable("testCache")
public Object varArgsKey(Object... args) { public Object varArgsKey(Object... args) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", key = "#root.methodName + #root.caches[0].name") @Cacheable(cacheNames = "testCache", key = "#root.methodName + #root.caches[0].name")
public Object name(Object arg1) { public Object name(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") @Cacheable(cacheNames = "testCache", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
public Object rootVars(Object arg1) { public Object rootVars(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", keyGenerator = "customKyeGenerator") @Cacheable(cacheNames = "testCache", keyGenerator = "customKyeGenerator")
public Object customKeyGenerator(Object arg1) { public Object customKeyGenerator(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", keyGenerator = "unknownBeanName") @Cacheable(cacheNames = "testCache", keyGenerator = "unknownBeanName")
public Object unknownCustomKeyGenerator(Object arg1) { public Object unknownCustomKeyGenerator(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", cacheManager = "customCacheManager") @Cacheable(cacheNames = "testCache", cacheManager = "customCacheManager")
public Object customCacheManager(Object arg1) { public Object customCacheManager(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", cacheManager = "unknownBeanName") @Cacheable(cacheNames = "testCache", cacheManager = "unknownBeanName")
public Object unknownCustomCacheManager(Object arg1) { public Object unknownCustomCacheManager(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@ -139,7 +139,7 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
} }
@Override @Override
@CachePut(value = "testCache", condition = "#arg.equals(3)") @CachePut(cacheNames = "testCache", condition = "#arg.equals(3)")
public Object conditionalUpdate(Object arg) { public Object conditionalUpdate(Object arg) {
return arg; return arg;
} }
@ -174,19 +174,19 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
} }
@Override @Override
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#a0"), @CacheEvict(value = "primary", key = "#p0 + 'A'") }) @Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#a0"), @CacheEvict(cacheNames = "primary", key = "#p0 + 'A'") })
public Object multiEvict(Object arg1) { public Object multiEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) @Caching(cacheable = { @Cacheable(cacheNames = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
public Object multiCacheAndEvict(Object arg1) { public Object multiCacheAndEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#a0 == 3") }, evict = { @CacheEvict("secondary") }) @Caching(cacheable = { @Cacheable(cacheNames = "primary", condition = "#a0 == 3") }, evict = { @CacheEvict("secondary") })
public Object multiConditionalCacheAndEvict(Object arg1) { public Object multiConditionalCacheAndEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@ -198,7 +198,7 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
} }
@Override @Override
@CachePut(value="primary", key="#result.id") @CachePut(cacheNames = "primary", key = "#result.id")
public TestEntity putRefersToResult(TestEntity arg1) { public TestEntity putRefersToResult(TestEntity arg1) {
arg1.setId(Long.MIN_VALUE); arg1.setId(Long.MIN_VALUE);
return arg1; return arg1;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2014 the original author or authors. * Copyright 2002-2015 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -53,83 +53,83 @@ public class DefaultCacheableService implements CacheableService<Long> {
} }
@Override @Override
@CacheEvict(value = "testCache", allEntries = true) @CacheEvict(cacheNames = "testCache", allEntries = true)
public void evictAll(Object arg1) { public void evictAll(Object arg1) {
} }
@Override @Override
@CacheEvict(value = "testCache", beforeInvocation = true) @CacheEvict(cacheNames = "testCache", beforeInvocation = true)
public void evictEarly(Object arg1) { public void evictEarly(Object arg1) {
throw new RuntimeException("exception thrown - evict should still occur"); throw new RuntimeException("exception thrown - evict should still occur");
} }
@Override @Override
@CacheEvict(value = "testCache", key = "#p0") @CacheEvict(cacheNames = "testCache", key = "#p0")
public void evict(Object arg1, Object arg2) { public void evict(Object arg1, Object arg2) {
} }
@Override @Override
@CacheEvict(value = "testCache", key = "#p0", beforeInvocation = true) @CacheEvict(cacheNames = "testCache", key = "#p0", beforeInvocation = true)
public void invalidateEarly(Object arg1, Object arg2) { public void invalidateEarly(Object arg1, Object arg2) {
throw new RuntimeException("exception thrown - evict should still occur"); throw new RuntimeException("exception thrown - evict should still occur");
} }
@Override @Override
@Cacheable(value = "testCache", condition = "#classField == 3") @Cacheable(cacheNames = "testCache", condition = "#classField == 3")
public Long conditional(int classField) { public Long conditional(int classField) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", unless = "#result > 10") @Cacheable(cacheNames = "testCache", unless = "#result > 10")
public Long unless(int arg) { public Long unless(int arg) {
return (long) arg; return (long) arg;
} }
@Override @Override
@Cacheable(value = "testCache", key = "#p0") @Cacheable(cacheNames = "testCache", key = "#p0")
public Long key(Object arg1, Object arg2) { public Long key(Object arg1, Object arg2) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache") @Cacheable(cacheNames = "testCache")
public Long varArgsKey(Object... args) { public Long varArgsKey(Object... args) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", key = "#root.methodName") @Cacheable(cacheNames = "testCache", key = "#root.methodName")
public Long name(Object arg1) { public Long name(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target") @Cacheable(cacheNames = "testCache", key = "#root.methodName + #root.method.name + #root.targetClass + #root.target")
public Long rootVars(Object arg1) { public Long rootVars(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", keyGenerator = "customKeyGenerator") @Cacheable(cacheNames = "testCache", keyGenerator = "customKeyGenerator")
public Long customKeyGenerator(Object arg1) { public Long customKeyGenerator(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", keyGenerator = "unknownBeanName") @Cacheable(cacheNames = "testCache", keyGenerator = "unknownBeanName")
public Long unknownCustomKeyGenerator(Object arg1) { public Long unknownCustomKeyGenerator(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", cacheManager = "customCacheManager") @Cacheable(cacheNames = "testCache", cacheManager = "customCacheManager")
public Long customCacheManager(Object arg1) { public Long customCacheManager(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Cacheable(value = "testCache", cacheManager = "unknownBeanName") @Cacheable(cacheNames = "testCache", cacheManager = "unknownBeanName")
public Long unknownCustomCacheManager(Object arg1) { public Long unknownCustomCacheManager(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@ -141,7 +141,7 @@ public class DefaultCacheableService implements CacheableService<Long> {
} }
@Override @Override
@CachePut(value = "testCache", condition = "#arg.equals(3)") @CachePut(cacheNames = "testCache", condition = "#arg.equals(3)")
public Long conditionalUpdate(Object arg) { public Long conditionalUpdate(Object arg) {
return Long.valueOf(arg.toString()); return Long.valueOf(arg.toString());
} }
@ -179,19 +179,19 @@ public class DefaultCacheableService implements CacheableService<Long> {
} }
@Override @Override
@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0"), @CacheEvict(value = "primary", key = "#p0 + 'A'") }) @Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames = "secondary", key = "#p0"), @CacheEvict(cacheNames = "primary", key = "#p0 + 'A'") })
public Long multiEvict(Object arg1) { public Long multiEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Caching(cacheable = { @Cacheable(value = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") }) @Caching(cacheable = { @Cacheable(cacheNames = "primary", key = "#root.methodName") }, evict = { @CacheEvict("secondary") })
public Long multiCacheAndEvict(Object arg1) { public Long multiCacheAndEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@Override @Override
@Caching(cacheable = { @Cacheable(value = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") }) @Caching(cacheable = { @Cacheable(cacheNames = "primary", condition = "#p0 == 3") }, evict = { @CacheEvict("secondary") })
public Long multiConditionalCacheAndEvict(Object arg1) { public Long multiConditionalCacheAndEvict(Object arg1) {
return counter.getAndIncrement(); return counter.getAndIncrement();
} }
@ -203,9 +203,10 @@ public class DefaultCacheableService implements CacheableService<Long> {
} }
@Override @Override
@CachePut(value="primary", key="#result.id") @CachePut(cacheNames = "primary", key = "#result.id")
public TestEntity putRefersToResult(TestEntity arg1) { public TestEntity putRefersToResult(TestEntity arg1) {
arg1.setId(Long.MIN_VALUE); arg1.setId(Long.MIN_VALUE);
return arg1; return arg1;
} }
} }