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
pull/5289/head
Stephane Nicoll 9 years ago
parent f04b517adb
commit d9f4d6ce91

@ -38,7 +38,6 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.CacheAspectSupport; import org.springframework.cache.interceptor.CacheAspectSupport;
import org.springframework.cache.interceptor.CacheResolver;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
@ -62,7 +61,7 @@ import org.springframework.util.Assert;
@Configuration @Configuration
@ConditionalOnClass(CacheManager.class) @ConditionalOnClass(CacheManager.class)
@ConditionalOnBean(CacheAspectSupport.class) @ConditionalOnBean(CacheAspectSupport.class)
@ConditionalOnMissingBean({ CacheManager.class, CacheResolver.class }) @ConditionalOnMissingBean(value = CacheManager.class, name = "cacheResolver")
@EnableConfigurationProperties(CacheProperties.class) @EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class) @AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
@AutoConfigureAfter({ HazelcastAutoConfiguration.class, RedisAutoConfiguration.class }) @AutoConfigureAfter({ HazelcastAutoConfiguration.class, RedisAutoConfiguration.class })

@ -127,12 +127,19 @@ public class CacheAutoConfigurationTests {
} }
@Test @Test
public void cacheResolverBackOff() throws Exception { public void cacheResolverFromSupportBackOff() throws Exception {
load(CustomCacheResolverConfiguration.class); load(CustomCacheResolverFromSupportConfiguration.class);
this.thrown.expect(NoSuchBeanDefinitionException.class); this.thrown.expect(NoSuchBeanDefinitionException.class);
this.context.getBean(CacheManager.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 @Test
public void notSupportedCachingMode() { public void notSupportedCachingMode() {
this.thrown.expect(BeanCreationException.class); this.thrown.expect(BeanCreationException.class);
@ -833,7 +840,7 @@ public class CacheAutoConfigurationTests {
} }
@Configuration @Configuration
@Import({ GenericCacheConfiguration.class, RedisCacheConfiguration.class }) @EnableCaching
static class CustomCacheManagerConfiguration { static class CustomCacheManagerConfiguration {
@Bean @Bean
@ -844,7 +851,7 @@ public class CacheAutoConfigurationTests {
} }
@Configuration @Configuration
@Import({ GenericCacheConfiguration.class, RedisCacheConfiguration.class }) @EnableCaching
static class CustomCacheManagerFromSupportConfiguration static class CustomCacheManagerFromSupportConfiguration
extends CachingConfigurerSupport { extends CachingConfigurerSupport {
@ -859,18 +866,7 @@ public class CacheAutoConfigurationTests {
@Configuration @Configuration
@EnableCaching @EnableCaching
static class GuavaCacheBuilderConfiguration { static class CustomCacheResolverFromSupportConfiguration extends CachingConfigurerSupport {
@Bean
CacheBuilder<Object, Object> cacheBuilder() {
return CacheBuilder.newBuilder().recordStats();
}
}
@Configuration
@Import({ GenericCacheConfiguration.class, RedisCacheConfiguration.class })
static class CustomCacheResolverConfiguration extends CachingConfigurerSupport {
@Override @Override
@Bean @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<Object, Object> cacheBuilder() {
return CacheBuilder.newBuilder().recordStats();
}
}
@Configuration @Configuration
@EnableCaching @EnableCaching
static class CaffeineCacheBuilderConfiguration { static class CaffeineCacheBuilderConfiguration {

@ -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 dependencies. If you are adding dependencies manually you should note that certain
implementations are only provided by the `spring-context-support` jar. 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):
* <<boot-features-caching-provider-generic,Generic>> * <<boot-features-caching-provider-generic,Generic>>
* <<boot-features-caching-provider-jcache,JCache (JSR-107)>> * <<boot-features-caching-provider-jcache,JCache (JSR-107)>>

Loading…
Cancel
Save