From d07ed31fed1cd88b6d078c1f9e2e4edd5fc5c056 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Thu, 3 Jul 2025 17:16:23 +0200 Subject: [PATCH 1/2] =?UTF-8?q?Support=20@=E2=81=A0CacheConfig("myCache")?= =?UTF-8?q?=20declarations=20for=20simplified=20config?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The @⁠CacheConfig section of the reference manual provides an example that declares @⁠CacheConfig("books"). However, unlike the @⁠Cacheable, @⁠CachePut, and @⁠CacheEvict annotations, @⁠CacheConfig currently does not have a `value` alias for the `cacheNames` attribute. Thus, the example in the reference manual does not compile, and @⁠CacheConfig(cacheNames = "books") would be the supported way to declare that. The driving factor for this commit is therefore to provide a simplified and consistent programming model for users that only need to define default cache names at the type level (like in the existing example in the reference manual). To address that, this commit introduces a `value` alias for `cacheNames` in @⁠CacheConfig. See gh-35096 Closes gh-35152 (cherry picked from commit 6091453feb9538d014e0cf3f584c3e12d6123136) --- .../caffeine/CaffeineReactiveCachingTests.java | 2 +- .../cache/annotation/CacheConfig.java | 13 +++++++++++++ .../AnnotationCacheOperationSourceTests.java | 2 +- .../cache/annotation/ReactiveCachingTests.java | 6 +++--- .../cache/config/EnableCachingIntegrationTests.java | 2 +- .../cache/interceptor/CacheErrorHandlerTests.java | 2 +- .../cache/interceptor/CachePutEvaluationTests.java | 2 +- .../CacheResolverCustomizationTests.java | 2 +- 8 files changed, 22 insertions(+), 9 deletions(-) diff --git a/spring-context-support/src/test/java/org/springframework/cache/caffeine/CaffeineReactiveCachingTests.java b/spring-context-support/src/test/java/org/springframework/cache/caffeine/CaffeineReactiveCachingTests.java index ba2034c4362..cd26be375cc 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/caffeine/CaffeineReactiveCachingTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/caffeine/CaffeineReactiveCachingTests.java @@ -129,7 +129,7 @@ class CaffeineReactiveCachingTests { } - @CacheConfig(cacheNames = "first") + @CacheConfig("first") static class ReactiveCacheableService { private final AtomicLong counter = new AtomicLong(); diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java b/spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java index 1521692245e..5ee1875a5bb 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java @@ -22,6 +22,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.springframework.core.annotation.AliasFor; + /** * {@code @CacheConfig} provides a mechanism for sharing common cache-related * settings at the class level. @@ -39,6 +41,15 @@ import java.lang.annotation.Target; @Documented public @interface CacheConfig { + /** + * Alias for {@link #cacheNames}. + *

Intended to be used when no other attributes are needed, for example: + * {@code @CacheConfig("books")}. + * @since 6.2.9 + */ + @AliasFor("cacheNames") + String[] value() default {}; + /** * Names of the default caches to consider for caching operations defined * in the annotated class. @@ -47,7 +58,9 @@ public @interface CacheConfig { * configured {@link #cacheResolver()} which typically delegates to * {@link org.springframework.cache.CacheManager#getCache}. * For further details see {@link Cacheable#cacheNames()}. + * @see #value */ + @AliasFor("value") String[] cacheNames() default {}; /** 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 a9f45200d3d..f6af1a5857f 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 @@ -443,7 +443,7 @@ class AnnotationCacheOperationSourceTests { } - @CacheConfig(cacheNames = "myCache") + @CacheConfig("myCache") private interface CacheConfigIfc { @Cacheable diff --git a/spring-context/src/test/java/org/springframework/cache/annotation/ReactiveCachingTests.java b/spring-context/src/test/java/org/springframework/cache/annotation/ReactiveCachingTests.java index c09db24e22a..75e9eb5a82d 100644 --- a/spring-context/src/test/java/org/springframework/cache/annotation/ReactiveCachingTests.java +++ b/spring-context/src/test/java/org/springframework/cache/annotation/ReactiveCachingTests.java @@ -259,7 +259,7 @@ class ReactiveCachingTests { } - @CacheConfig(cacheNames = "first") + @CacheConfig("first") static class ReactiveCacheableService { private final AtomicLong counter = new AtomicLong(); @@ -285,7 +285,7 @@ class ReactiveCachingTests { } - @CacheConfig(cacheNames = "first") + @CacheConfig("first") static class ReactiveSyncCacheableService { private final AtomicLong counter = new AtomicLong(); @@ -307,7 +307,7 @@ class ReactiveCachingTests { } - @CacheConfig(cacheNames = "first") + @CacheConfig("first") static class ReactiveFailureCacheableService { private final AtomicBoolean cacheFutureInvoked = new AtomicBoolean(); diff --git a/spring-context/src/test/java/org/springframework/cache/config/EnableCachingIntegrationTests.java b/spring-context/src/test/java/org/springframework/cache/config/EnableCachingIntegrationTests.java index f2da9f99379..2208e54bc0d 100644 --- a/spring-context/src/test/java/org/springframework/cache/config/EnableCachingIntegrationTests.java +++ b/spring-context/src/test/java/org/springframework/cache/config/EnableCachingIntegrationTests.java @@ -200,7 +200,7 @@ class EnableCachingIntegrationTests { } - @CacheConfig(cacheNames = "testCache") + @CacheConfig("testCache") static class FooServiceImpl implements FooService { private final AtomicLong counter = new AtomicLong(); diff --git a/spring-context/src/test/java/org/springframework/cache/interceptor/CacheErrorHandlerTests.java b/spring-context/src/test/java/org/springframework/cache/interceptor/CacheErrorHandlerTests.java index 926d2345d76..0446a1c1706 100644 --- a/spring-context/src/test/java/org/springframework/cache/interceptor/CacheErrorHandlerTests.java +++ b/spring-context/src/test/java/org/springframework/cache/interceptor/CacheErrorHandlerTests.java @@ -261,7 +261,7 @@ class CacheErrorHandlerTests { } - @CacheConfig(cacheNames = "test") + @CacheConfig("test") public static class SimpleService { private AtomicLong counter = new AtomicLong(); diff --git a/spring-context/src/test/java/org/springframework/cache/interceptor/CachePutEvaluationTests.java b/spring-context/src/test/java/org/springframework/cache/interceptor/CachePutEvaluationTests.java index 2884783f99c..50ad24d6f5b 100644 --- a/spring-context/src/test/java/org/springframework/cache/interceptor/CachePutEvaluationTests.java +++ b/spring-context/src/test/java/org/springframework/cache/interceptor/CachePutEvaluationTests.java @@ -121,7 +121,7 @@ class CachePutEvaluationTests { } - @CacheConfig(cacheNames = "test") + @CacheConfig("test") public static class SimpleService { private AtomicLong counter = new AtomicLong(); diff --git a/spring-context/src/test/java/org/springframework/cache/interceptor/CacheResolverCustomizationTests.java b/spring-context/src/test/java/org/springframework/cache/interceptor/CacheResolverCustomizationTests.java index 765c871e9b4..681b57a0061 100644 --- a/spring-context/src/test/java/org/springframework/cache/interceptor/CacheResolverCustomizationTests.java +++ b/spring-context/src/test/java/org/springframework/cache/interceptor/CacheResolverCustomizationTests.java @@ -206,7 +206,7 @@ class CacheResolverCustomizationTests { } - @CacheConfig(cacheNames = "default") + @CacheConfig("default") static class SimpleService { private final AtomicLong counter = new AtomicLong(); From ad00aebaa3ae436b79c8b3457aa6425401356db8 Mon Sep 17 00:00:00 2001 From: Sam Brannen <104798+sbrannen@users.noreply.github.com> Date: Mon, 7 Jul 2025 12:11:41 +0200 Subject: [PATCH 2/2] Improve Javadoc for caching annotations --- .../org/springframework/cache/annotation/CacheConfig.java | 2 ++ .../java/org/springframework/cache/annotation/CacheEvict.java | 4 ++++ .../java/org/springframework/cache/annotation/CachePut.java | 4 ++++ .../java/org/springframework/cache/annotation/Cacheable.java | 4 ++++ 4 files changed, 14 insertions(+) diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java b/spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java index 5ee1875a5bb..c5a3f9c4922 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/CacheConfig.java @@ -35,6 +35,8 @@ import org.springframework.core.annotation.AliasFor; * @author Sam Brannen * @since 4.1 * @see Cacheable + * @see CachePut + * @see CacheEvict */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/CacheEvict.java b/spring-context/src/main/java/org/springframework/cache/annotation/CacheEvict.java index 21becaf2b60..a85b2fef2bf 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/CacheEvict.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/CacheEvict.java @@ -38,6 +38,8 @@ import org.springframework.core.annotation.AliasFor; * @author Sam Brannen * @since 3.1 * @see CacheConfig + * @see Cacheable + * @see CachePut */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @@ -48,6 +50,8 @@ public @interface CacheEvict { /** * Alias for {@link #cacheNames}. + *

Intended to be used when no other attributes are needed, for example: + * {@code @CacheEvict("books")}. */ @AliasFor("cacheNames") String[] value() default {}; diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/CachePut.java b/spring-context/src/main/java/org/springframework/cache/annotation/CachePut.java index daf5788ac2a..74f1bf55003 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/CachePut.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/CachePut.java @@ -46,6 +46,8 @@ import org.springframework.core.annotation.AliasFor; * @author Sam Brannen * @since 3.1 * @see CacheConfig + * @see Cacheable + * @see CacheEvict */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @@ -56,6 +58,8 @@ public @interface CachePut { /** * Alias for {@link #cacheNames}. + *

Intended to be used when no other attributes are needed, for example: + * {@code @CachePut("books")}. */ @AliasFor("cacheNames") String[] value() default {}; diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/Cacheable.java b/spring-context/src/main/java/org/springframework/cache/annotation/Cacheable.java index 8164da481ea..fa24ab07524 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/Cacheable.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/Cacheable.java @@ -54,6 +54,8 @@ import org.springframework.core.annotation.AliasFor; * @author Sam Brannen * @since 3.1 * @see CacheConfig + * @see CachePut + * @see CacheEvict */ @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @@ -64,6 +66,8 @@ public @interface Cacheable { /** * Alias for {@link #cacheNames}. + *

Intended to be used when no other attributes are needed, for example: + * {@code @Cacheable("books")}. */ @AliasFor("cacheNames") String[] value() default {};