From 3d6b0ca5bee3578c7a433f44d0d86cf5e521b10d Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Apr 2016 13:25:29 +0200 Subject: [PATCH] SpringCacheAnnotationParser properly accepts empty @Caching annotation Issue: SPR-14162 --- .../SpringCacheAnnotationParser.java | 7 ++- .../AnnotationCacheOperationSourceTests.java | 53 ++++++++++++------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java b/spring-context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java index 2822d1124d..34144d9060 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/SpringCacheAnnotationParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 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. @@ -70,7 +70,10 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria if (cachings != null) { ops = lazyInit(ops); for (Caching caching : cachings) { - ops.addAll(parseCachingAnnotation(ae, caching)); + Collection cachingOps = parseCachingAnnotation(ae, caching); + if (cachingOps != null) { + ops.addAll(cachingOps); + } } } diff --git a/spring-context/src/test/java/org/springframework/cache/annotation/AnnotationCacheOperationSourceTests.java b/spring-context/src/test/java/org/springframework/cache/annotation/AnnotationCacheOperationSourceTests.java index 4c1632aacd..996e110362 100644 --- a/spring-context/src/test/java/org/springframework/cache/annotation/AnnotationCacheOperationSourceTests.java +++ b/spring-context/src/test/java/org/springframework/cache/annotation/AnnotationCacheOperationSourceTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2011 the original author or authors. + * Copyright 2002-2016 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,8 +16,6 @@ package org.springframework.cache.annotation; -import static org.junit.Assert.*; - import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -27,22 +25,20 @@ import java.util.Collection; import java.util.Iterator; import org.junit.Test; + import org.springframework.cache.interceptor.CacheEvictOperation; import org.springframework.cache.interceptor.CacheOperation; import org.springframework.cache.interceptor.CacheableOperation; -import org.springframework.util.ReflectionUtils; + +import static org.junit.Assert.*; /** * @author Costin Leau */ public class AnnotationCacheOperationSourceTests { - private AnnotationCacheOperationSource source = new AnnotationCacheOperationSource(); + private final AnnotationCacheOperationSource source = new AnnotationCacheOperationSource(); - private Collection getOps(String name) { - Method method = ReflectionUtils.findMethod(AnnotatedClass.class, name); - return source.getCacheOperations(method, AnnotatedClass.class); - } @Test public void testSingularAnnotation() throws Exception { @@ -69,6 +65,12 @@ public class AnnotationCacheOperationSourceTests { assertTrue(it.next() instanceof CacheEvictOperation); } + @Test + public void testEmptyCaching() throws Exception { + Collection ops = getOps("emptyCaching"); + assertTrue(ops.isEmpty()); + } + @Test public void testSingularStereotype() throws Exception { Collection ops = getOps("singleStereotype"); @@ -90,7 +92,15 @@ public class AnnotationCacheOperationSourceTests { assertTrue(next.getCacheNames().contains("bar")); } + + private Collection getOps(String name) throws Exception { + Method method = AnnotatedClass.class.getMethod(name); + return source.getCacheOperations(method, AnnotatedClass.class); + } + + private static class AnnotatedClass { + @Cacheable("test") public void singular() { } @@ -100,13 +110,16 @@ public class AnnotationCacheOperationSourceTests { public void multiple() { } - @Caching(cacheable = { @Cacheable("test") }, evict = { @CacheEvict("test") }) + @Caching(cacheable = @Cacheable("test"), evict = @CacheEvict("test")) public void caching() { } + @Caching + public void emptyCaching() { + } + @EvictFoo public void singleStereotype() { - } @EvictFoo @@ -120,21 +133,25 @@ public class AnnotationCacheOperationSourceTests { } } + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @Cacheable("foo") public @interface CacheableFoo { } - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - @CacheEvict(value = "foo") - public @interface EvictFoo { - } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) - @CacheEvict(value = "bar") + @CacheEvict("foo") + public @interface EvictFoo { + } + + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + @CacheEvict("bar") public @interface EvictBar { } -} \ No newline at end of file + +}