From d9f4d6ce912deea0bd064c9bb977bfa7973d5d01 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 29 Feb 2016 15:48:46 +0100 Subject: [PATCH] Allow custom CacheResolver Previously, if a bean of type `CacheResolver` was present in the context the whole cache auto-configuration would back off. If said `CacheResolver` hasn't been defined via the `CachingConfigurer` infrastructure, the application context would fail with a rather unpleasant error message. It can be quite common to define custom `CacheResolver` beans as the cache annotations allow to defines custom cache resolvers per operation. This commit makes sure that the cache auto-configuration will back-off only if the `CacheResolver` is named `cacheResolver`. Closes gh-5201 --- .../cache/CacheAutoConfiguration.java | 3 +- .../cache/CacheAutoConfigurationTests.java | 50 +++++++++++++------ .../main/asciidoc/spring-boot-features.adoc | 4 +- 3 files changed, 38 insertions(+), 19 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java index 52d0fe760e..8530bf48c2 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java @@ -38,7 +38,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.interceptor.CacheAspectSupport; -import org.springframework.cache.interceptor.CacheResolver; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @@ -62,7 +61,7 @@ import org.springframework.util.Assert; @Configuration @ConditionalOnClass(CacheManager.class) @ConditionalOnBean(CacheAspectSupport.class) -@ConditionalOnMissingBean({ CacheManager.class, CacheResolver.class }) +@ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver") @EnableConfigurationProperties(CacheProperties.class) @AutoConfigureBefore(HibernateJpaAutoConfiguration.class) @AutoConfigureAfter({ HazelcastAutoConfiguration.class, RedisAutoConfiguration.class }) diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfigurationTests.java index c19bb16bec..e765a07a85 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfigurationTests.java @@ -127,12 +127,19 @@ public class CacheAutoConfigurationTests { } @Test - public void cacheResolverBackOff() throws Exception { - load(CustomCacheResolverConfiguration.class); + public void cacheResolverFromSupportBackOff() throws Exception { + load(CustomCacheResolverFromSupportConfiguration.class); this.thrown.expect(NoSuchBeanDefinitionException.class); this.context.getBean(CacheManager.class); } + @Test + public void customCacheResolverCanBeDefined() throws Exception { + load(SpecificCacheResolverConfiguration.class, "spring.cache.type=simple"); + validateCacheManager(ConcurrentMapCacheManager.class); + assertThat(this.context.getBeansOfType(CacheResolver.class)).hasSize(1); + } + @Test public void notSupportedCachingMode() { this.thrown.expect(BeanCreationException.class); @@ -833,7 +840,7 @@ public class CacheAutoConfigurationTests { } @Configuration - @Import({ GenericCacheConfiguration.class, RedisCacheConfiguration.class }) + @EnableCaching static class CustomCacheManagerConfiguration { @Bean @@ -844,7 +851,7 @@ public class CacheAutoConfigurationTests { } @Configuration - @Import({ GenericCacheConfiguration.class, RedisCacheConfiguration.class }) + @EnableCaching static class CustomCacheManagerFromSupportConfiguration extends CachingConfigurerSupport { @@ -859,18 +866,7 @@ public class CacheAutoConfigurationTests { @Configuration @EnableCaching - static class GuavaCacheBuilderConfiguration { - - @Bean - CacheBuilder cacheBuilder() { - return CacheBuilder.newBuilder().recordStats(); - } - - } - - @Configuration - @Import({ GenericCacheConfiguration.class, RedisCacheConfiguration.class }) - static class CustomCacheResolverConfiguration extends CachingConfigurerSupport { + static class CustomCacheResolverFromSupportConfiguration extends CachingConfigurerSupport { @Override @Bean @@ -890,6 +886,28 @@ public class CacheAutoConfigurationTests { } + @Configuration + @EnableCaching + static class SpecificCacheResolverConfiguration { + + @Bean + public CacheResolver myCacheResolver() { + return mock(CacheResolver.class); + } + + } + + @Configuration + @EnableCaching + static class GuavaCacheBuilderConfiguration { + + @Bean + CacheBuilder cacheBuilder() { + return CacheBuilder.newBuilder().recordStats(); + } + + } + @Configuration @EnableCaching static class CaffeineCacheBuilderConfiguration { diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 972bc82fd7..33c0be8b7e 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -3241,7 +3241,9 @@ TIP: Use the `spring-boot-starter-cache` "`Starter POM`" to quickly add required dependencies. If you are adding dependencies manually you should note that certain implementations are only provided by the `spring-context-support` jar. -Spring Boot tries to detect the following providers (in this order): +If you haven't defined a bean of type `CacheManager` or a `CacheResolver` named +`cacheResolver` (see `CachingConfigurer`), Spring Boot tries to detect the following +providers (in this order): * <> * <>