Caching annotations on interface methods with CGLIB proxies

Issue: SPR-15271
master
Juergen Hoeller 8 years ago
parent 6c43d14a77
commit 8b50f887db
  1. 28
      spring-context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java
  2. 3
      spring-context/src/test/java/org/springframework/cache/CacheReproTests.java
  3. 3
      spring-context/src/test/java/org/springframework/cache/annotation/AnnotationCacheOperationSourceTests.java

@ -59,30 +59,48 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
}
protected Collection<CacheOperation> parseCacheAnnotations(DefaultCacheConfig cachingConfig, AnnotatedElement ae) {
Collection<CacheOperation> ops = parseCacheAnnotations(cachingConfig, ae, false);
if (ops != null && ops.size() > 1 && ae.getAnnotations().length > 0) {
// More than one operation found -> local declarations override interface-declared ones...
Collection<CacheOperation> localOps = parseCacheAnnotations(cachingConfig, ae, true);
if (localOps != null) {
return localOps;
}
}
return ops;
}
private Collection<CacheOperation> parseCacheAnnotations(
DefaultCacheConfig cachingConfig, AnnotatedElement ae, boolean localOnly) {
Collection<CacheOperation> ops = null;
Collection<Cacheable> cacheables = AnnotatedElementUtils.getAllMergedAnnotations(ae, Cacheable.class);
Collection<Cacheable> cacheables = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, Cacheable.class) :
AnnotatedElementUtils.findAllMergedAnnotations(ae, Cacheable.class));
if (!cacheables.isEmpty()) {
ops = lazyInit(ops);
for (Cacheable cacheable : cacheables) {
ops.add(parseCacheableAnnotation(ae, cachingConfig, cacheable));
}
}
Collection<CacheEvict> evicts = AnnotatedElementUtils.getAllMergedAnnotations(ae, CacheEvict.class);
Collection<CacheEvict> evicts = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, CacheEvict.class) :
AnnotatedElementUtils.findAllMergedAnnotations(ae, CacheEvict.class));
if (!evicts.isEmpty()) {
ops = lazyInit(ops);
for (CacheEvict evict : evicts) {
ops.add(parseEvictAnnotation(ae, cachingConfig, evict));
}
}
Collection<CachePut> puts = AnnotatedElementUtils.getAllMergedAnnotations(ae, CachePut.class);
Collection<CachePut> puts = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, CachePut.class) :
AnnotatedElementUtils.findAllMergedAnnotations(ae, CachePut.class));
if (!puts.isEmpty()) {
ops = lazyInit(ops);
for (CachePut put : puts) {
ops.add(parsePutAnnotation(ae, cachingConfig, put));
}
}
Collection<Caching> cachings = AnnotatedElementUtils.getAllMergedAnnotations(ae, Caching.class);
Collection<Caching> cachings = (localOnly ? AnnotatedElementUtils.getAllMergedAnnotations(ae, Caching.class) :
AnnotatedElementUtils.findAllMergedAnnotations(ae, Caching.class));
if (!cachings.isEmpty()) {
ops = lazyInit(ops);
for (Caching caching : cachings) {
@ -193,7 +211,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
* @return the default config (never {@code null})
*/
DefaultCacheConfig getDefaultCacheConfig(Class<?> target) {
CacheConfig annotation = AnnotatedElementUtils.getMergedAnnotation(target, CacheConfig.class);
CacheConfig annotation = AnnotatedElementUtils.findMergedAnnotation(target, CacheConfig.class);
if (annotation != null) {
return new DefaultCacheConfig(annotation.cacheNames(), annotation.keyGenerator(),
annotation.cacheManager(), annotation.cacheResolver());

@ -21,7 +21,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Optional;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@ -180,7 +179,7 @@ public class CacheReproTests {
assertSame(tb, cache.get("tb1").get());
}
@Test @Ignore // TODO
@Test
public void spr15271FindsOnInterfaceWithCglibProxy() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Spr15271ConfigB.class);
Spr15271Interface bean = context.getBean(Spr15271Interface.class);

@ -246,8 +246,7 @@ public class AnnotationCacheOperationSourceTests {
@Test
public void cacheConfigFromInterface() {
assertNull(getOps(InterfaceCacheConfig.class, "interfaceCacheConfig"));
Collection<CacheOperation> ops = getOps(CacheConfigIfc.class, "interfaceCacheConfig");
Collection<CacheOperation> ops = getOps(InterfaceCacheConfig.class, "interfaceCacheConfig");
CacheOperation cacheOperation = ops.iterator().next();
assertSharedConfig(cacheOperation, "", "", "", "myCache");
}

Loading…
Cancel
Save