Commit c93ea54e authored by Phillip Webb's avatar Phillip Webb

Merge branch '1.3.x'

parents 8b587a87 4fd778fe
...@@ -66,7 +66,7 @@ import org.springframework.util.Assert; ...@@ -66,7 +66,7 @@ import org.springframework.util.Assert;
@EnableConfigurationProperties(CacheProperties.class) @EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class) @AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
@AutoConfigureAfter({ HazelcastAutoConfiguration.class, RedisAutoConfiguration.class }) @AutoConfigureAfter({ HazelcastAutoConfiguration.class, RedisAutoConfiguration.class })
@Import({ CacheManagerCustomizerInvoker.class, CacheConfigurationImportSelector.class }) @Import({ CacheManagerCustomizers.class, CacheConfigurationImportSelector.class })
public class CacheAutoConfiguration { public class CacheAutoConfiguration {
static final String VALIDATOR_BEAN_NAME = "cacheAutoConfigurationValidator"; static final String VALIDATOR_BEAN_NAME = "cacheAutoConfigurationValidator";
......
...@@ -22,16 +22,16 @@ import org.springframework.cache.CacheManager; ...@@ -22,16 +22,16 @@ import org.springframework.cache.CacheManager;
* Callback interface that can be implemented by beans wishing to customize the cache * Callback interface that can be implemented by beans wishing to customize the cache
* manager before it is fully initialized, in particular to tune its configuration. * manager before it is fully initialized, in particular to tune its configuration.
* *
* @param <C> The type of the {@link CacheManager} * @param <T> The type of the {@link CacheManager}
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.3 * @since 1.3.3
*/ */
public interface CacheManagerCustomizer<C extends CacheManager> { public interface CacheManagerCustomizer<T extends CacheManager> {
/** /**
* Customize the cache manager. * Customize the cache manager.
* @param cacheManager the {@code CacheManager} to customize * @param cacheManager the {@code CacheManager} to customize
*/ */
void customize(C cacheManager); void customize(T cacheManager);
} }
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
package org.springframework.boot.autoconfigure.cache; package org.springframework.boot.autoconfigure.cache;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanFactoryUtils;
...@@ -31,12 +31,12 @@ import org.springframework.core.GenericTypeResolver; ...@@ -31,12 +31,12 @@ import org.springframework.core.GenericTypeResolver;
import org.springframework.core.annotation.AnnotationAwareOrderComparator; import org.springframework.core.annotation.AnnotationAwareOrderComparator;
/** /**
* Invoke the available {@link CacheManagerCustomizer} instances in the context for a * Invokes the available {@link CacheManagerCustomizer} instances in the context for a
* given {@link CacheManager}. * given {@link CacheManager}.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
*/ */
class CacheManagerCustomizerInvoker implements ApplicationContextAware { class CacheManagerCustomizers implements ApplicationContextAware {
private ConfigurableApplicationContext applicationContext; private ConfigurableApplicationContext applicationContext;
...@@ -45,14 +45,16 @@ class CacheManagerCustomizerInvoker implements ApplicationContextAware { ...@@ -45,14 +45,16 @@ class CacheManagerCustomizerInvoker implements ApplicationContextAware {
* {@link CacheManagerCustomizer} beans able to handle the specified instance and * {@link CacheManagerCustomizer} beans able to handle the specified instance and
* invoke {@link CacheManagerCustomizer#customize(CacheManager)} on them. * invoke {@link CacheManagerCustomizer#customize(CacheManager)} on them.
* @param cacheManager the cache manager to customize * @param cacheManager the cache manager to customize
* @return the cache manager
*/ */
public void customize(CacheManager cacheManager) { public <T extends CacheManager> T customize(T cacheManager) {
List<CacheManagerCustomizer<CacheManager>> customizers = findCustomizers( List<CacheManagerCustomizer<CacheManager>> customizers = findCustomizers(
cacheManager); cacheManager);
AnnotationAwareOrderComparator.sort(customizers); AnnotationAwareOrderComparator.sort(customizers);
for (CacheManagerCustomizer<CacheManager> customizer : customizers) { for (CacheManagerCustomizer<CacheManager> customizer : customizers) {
customizer.customize(cacheManager); customizer.customize(cacheManager);
} }
return cacheManager;
} }
@SuppressWarnings({ "unchecked", "rawtypes" }) @SuppressWarnings({ "unchecked", "rawtypes" })
...@@ -61,20 +63,28 @@ class CacheManagerCustomizerInvoker implements ApplicationContextAware { ...@@ -61,20 +63,28 @@ class CacheManagerCustomizerInvoker implements ApplicationContextAware {
if (this.applicationContext == null) { if (this.applicationContext == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
Map<String, CacheManagerCustomizer> map = BeanFactoryUtils Class<?> cacheManagerClass = cacheManager.getClass();
.beansOfTypeIncludingAncestors(this.applicationContext.getBeanFactory(),
CacheManagerCustomizer.class);
List<CacheManagerCustomizer<CacheManager>> customizers = new ArrayList<CacheManagerCustomizer<CacheManager>>(); List<CacheManagerCustomizer<CacheManager>> customizers = new ArrayList<CacheManagerCustomizer<CacheManager>>();
for (CacheManagerCustomizer customizer : map.values()) { for (CacheManagerCustomizer customizer : getBeans(CacheManagerCustomizer.class)) {
Class<?> target = GenericTypeResolver.resolveTypeArgument( if (canCustomize(customizer, cacheManagerClass)) {
customizer.getClass(), CacheManagerCustomizer.class);
if (target == null || target.isAssignableFrom(cacheManager.getClass())) {
customizers.add(customizer); customizers.add(customizer);
} }
} }
return customizers; return customizers;
} }
private <T> Collection<T> getBeans(Class<T> type) {
return BeanFactoryUtils.beansOfTypeIncludingAncestors(
this.applicationContext.getBeanFactory(), type).values();
}
private boolean canCustomize(CacheManagerCustomizer<?> customizer,
Class<?> cacheManagerClass) {
Class<?> target = GenericTypeResolver.resolveTypeArgument(customizer.getClass(),
CacheManagerCustomizer.class);
return (target == null || target.isAssignableFrom(cacheManagerClass));
}
@Override @Override
public void setApplicationContext(ApplicationContext applicationContext) public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException { throws BeansException {
......
...@@ -49,13 +49,11 @@ class EhCacheCacheConfiguration { ...@@ -49,13 +49,11 @@ class EhCacheCacheConfiguration {
private CacheProperties cacheProperties; private CacheProperties cacheProperties;
@Autowired @Autowired
CacheManagerCustomizerInvoker customizerInvoker; private CacheManagerCustomizers customizers;
@Bean @Bean
public EhCacheCacheManager cacheManager(CacheManager ehCacheCacheManager) { public EhCacheCacheManager cacheManager(CacheManager ehCacheCacheManager) {
EhCacheCacheManager cacheManager = new EhCacheCacheManager(ehCacheCacheManager); return this.customizers.customize(new EhCacheCacheManager(ehCacheCacheManager));
this.customizerInvoker.customize(cacheManager);
return cacheManager;
} }
@Bean @Bean
......
...@@ -42,14 +42,13 @@ import org.springframework.context.annotation.Configuration; ...@@ -42,14 +42,13 @@ import org.springframework.context.annotation.Configuration;
class GenericCacheConfiguration { class GenericCacheConfiguration {
@Autowired @Autowired
CacheManagerCustomizerInvoker customizerInvoker; private CacheManagerCustomizers customizers;
@Bean @Bean
public SimpleCacheManager cacheManager(Collection<Cache> caches) { public SimpleCacheManager cacheManager(Collection<Cache> caches) {
SimpleCacheManager cacheManager = new SimpleCacheManager(); SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(caches); cacheManager.setCaches(caches);
this.customizerInvoker.customize(cacheManager); return this.customizers.customize(cacheManager);
return cacheManager;
} }
} }
...@@ -49,7 +49,7 @@ class GuavaCacheConfiguration { ...@@ -49,7 +49,7 @@ class GuavaCacheConfiguration {
private CacheProperties cacheProperties; private CacheProperties cacheProperties;
@Autowired @Autowired
CacheManagerCustomizerInvoker customizerInvoker; private CacheManagerCustomizers customizers;
@Autowired(required = false) @Autowired(required = false)
private CacheBuilder<Object, Object> cacheBuilder; private CacheBuilder<Object, Object> cacheBuilder;
...@@ -67,8 +67,7 @@ class GuavaCacheConfiguration { ...@@ -67,8 +67,7 @@ class GuavaCacheConfiguration {
if (!CollectionUtils.isEmpty(cacheNames)) { if (!CollectionUtils.isEmpty(cacheNames)) {
cacheManager.setCacheNames(cacheNames); cacheManager.setCacheNames(cacheNames);
} }
this.customizerInvoker.customize(cacheManager); return this.customizers.customize(cacheManager);
return cacheManager;
} }
private GuavaCacheManager createCacheManager() { private GuavaCacheManager createCacheManager() {
......
...@@ -49,7 +49,7 @@ abstract class HazelcastInstanceConfiguration { ...@@ -49,7 +49,7 @@ abstract class HazelcastInstanceConfiguration {
private CacheProperties cacheProperties; private CacheProperties cacheProperties;
@Autowired @Autowired
CacheManagerCustomizerInvoker customizerInvoker; private CacheManagerCustomizers customizers;
@Bean @Bean
public HazelcastCacheManager cacheManager( public HazelcastCacheManager cacheManager(
...@@ -63,8 +63,7 @@ abstract class HazelcastInstanceConfiguration { ...@@ -63,8 +63,7 @@ abstract class HazelcastInstanceConfiguration {
} }
HazelcastCacheManager cacheManager = new HazelcastCacheManager( HazelcastCacheManager cacheManager = new HazelcastCacheManager(
existingHazelcastInstance); existingHazelcastInstance);
this.customizerInvoker.customize(cacheManager); return this.customizers.customize(cacheManager);
return cacheManager;
} }
} }
...@@ -77,7 +76,7 @@ abstract class HazelcastInstanceConfiguration { ...@@ -77,7 +76,7 @@ abstract class HazelcastInstanceConfiguration {
private CacheProperties cacheProperties; private CacheProperties cacheProperties;
@Autowired @Autowired
CacheManagerCustomizerInvoker customizerInvoker; private CacheManagerCustomizers customizers;
@Bean @Bean
public HazelcastInstance hazelcastInstance() throws IOException { public HazelcastInstance hazelcastInstance() throws IOException {
...@@ -93,8 +92,7 @@ abstract class HazelcastInstanceConfiguration { ...@@ -93,8 +92,7 @@ abstract class HazelcastInstanceConfiguration {
public HazelcastCacheManager cacheManager() throws IOException { public HazelcastCacheManager cacheManager() throws IOException {
HazelcastCacheManager cacheManager = new HazelcastCacheManager( HazelcastCacheManager cacheManager = new HazelcastCacheManager(
hazelcastInstance()); hazelcastInstance());
this.customizerInvoker.customize(cacheManager); return this.customizers.customize(cacheManager);
return cacheManager;
} }
} }
......
...@@ -52,7 +52,7 @@ public class InfinispanCacheConfiguration { ...@@ -52,7 +52,7 @@ public class InfinispanCacheConfiguration {
private CacheProperties cacheProperties; private CacheProperties cacheProperties;
@Autowired @Autowired
CacheManagerCustomizerInvoker customizerInvoker; private CacheManagerCustomizers customizers;
@Autowired(required = false) @Autowired(required = false)
private ConfigurationBuilder defaultConfigurationBuilder; private ConfigurationBuilder defaultConfigurationBuilder;
...@@ -62,8 +62,7 @@ public class InfinispanCacheConfiguration { ...@@ -62,8 +62,7 @@ public class InfinispanCacheConfiguration {
EmbeddedCacheManager embeddedCacheManager) { EmbeddedCacheManager embeddedCacheManager) {
SpringEmbeddedCacheManager cacheManager = new SpringEmbeddedCacheManager( SpringEmbeddedCacheManager cacheManager = new SpringEmbeddedCacheManager(
embeddedCacheManager); embeddedCacheManager);
this.customizerInvoker.customize(cacheManager); return this.customizers.customize(cacheManager);
return cacheManager;
} }
@Bean(destroyMethod = "stop") @Bean(destroyMethod = "stop")
......
...@@ -64,7 +64,7 @@ class JCacheCacheConfiguration { ...@@ -64,7 +64,7 @@ class JCacheCacheConfiguration {
private CacheProperties cacheProperties; private CacheProperties cacheProperties;
@Autowired @Autowired
CacheManagerCustomizerInvoker customizerInvoker; private CacheManagerCustomizers customizers;
@Autowired(required = false) @Autowired(required = false)
private javax.cache.configuration.Configuration<?, ?> defaultCacheConfiguration; private javax.cache.configuration.Configuration<?, ?> defaultCacheConfiguration;
...@@ -75,8 +75,7 @@ class JCacheCacheConfiguration { ...@@ -75,8 +75,7 @@ class JCacheCacheConfiguration {
@Bean @Bean
public JCacheCacheManager cacheManager(CacheManager jCacheCacheManager) { public JCacheCacheManager cacheManager(CacheManager jCacheCacheManager) {
JCacheCacheManager cacheManager = new JCacheCacheManager(jCacheCacheManager); JCacheCacheManager cacheManager = new JCacheCacheManager(jCacheCacheManager);
this.customizerInvoker.customize(cacheManager); return this.customizers.customize(cacheManager);
return cacheManager;
} }
@Bean @Bean
......
...@@ -47,7 +47,7 @@ class RedisCacheConfiguration { ...@@ -47,7 +47,7 @@ class RedisCacheConfiguration {
private CacheProperties cacheProperties; private CacheProperties cacheProperties;
@Autowired @Autowired
CacheManagerCustomizerInvoker customizerInvoker; private CacheManagerCustomizers customizerInvoker;
@Bean @Bean
public RedisCacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) { public RedisCacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) {
...@@ -57,8 +57,7 @@ class RedisCacheConfiguration { ...@@ -57,8 +57,7 @@ class RedisCacheConfiguration {
if (!cacheNames.isEmpty()) { if (!cacheNames.isEmpty()) {
cacheManager.setCacheNames(cacheNames); cacheManager.setCacheNames(cacheNames);
} }
this.customizerInvoker.customize(cacheManager); return this.customizerInvoker.customize(cacheManager);
return cacheManager;
} }
} }
...@@ -41,7 +41,7 @@ class SimpleCacheConfiguration { ...@@ -41,7 +41,7 @@ class SimpleCacheConfiguration {
private CacheProperties cacheProperties; private CacheProperties cacheProperties;
@Autowired @Autowired
CacheManagerCustomizerInvoker customizerInvoker; private CacheManagerCustomizers customizerInvoker;
@Bean @Bean
public ConcurrentMapCacheManager cacheManager() { public ConcurrentMapCacheManager cacheManager() {
...@@ -50,8 +50,7 @@ class SimpleCacheConfiguration { ...@@ -50,8 +50,7 @@ class SimpleCacheConfiguration {
if (!cacheNames.isEmpty()) { if (!cacheNames.isEmpty()) {
cacheManager.setCacheNames(cacheNames); cacheManager.setCacheNames(cacheNames);
} }
this.customizerInvoker.customize(cacheManager); return this.customizerInvoker.customize(cacheManager);
return cacheManager;
} }
} }
...@@ -454,8 +454,10 @@ public class CacheAutoConfigurationTests { ...@@ -454,8 +454,10 @@ public class CacheAutoConfigurationTests {
load(DefaultCacheConfiguration.class, "spring.cache.type=jcache", load(DefaultCacheConfiguration.class, "spring.cache.type=jcache",
"spring.cache.jcache.provider=" + cachingProviderFqn, "spring.cache.jcache.provider=" + cachingProviderFqn,
"spring.cache.cacheNames[0]=foo", "spring.cache.cacheNames[1]=bar"); "spring.cache.cacheNames[0]=foo", "spring.cache.cacheNames[1]=bar");
JCacheCacheManager cacheManager = validateCacheManager(JCacheCacheManager.class); JCacheCacheManager cacheManager = validateCacheManager(
JCacheCacheManager.class);
assertThat(cacheManager.getCacheNames()).containsOnly("foo", "bar"); assertThat(cacheManager.getCacheNames()).containsOnly("foo", "bar");
assertThat(cacheManager.getCacheNames()).hasSize(2);
} }
finally { finally {
Caching.getCachingProvider(cachingProviderFqn).close(); Caching.getCachingProvider(cachingProviderFqn).close();
...@@ -889,18 +891,19 @@ public class CacheAutoConfigurationTests { ...@@ -889,18 +891,19 @@ public class CacheAutoConfigurationTests {
} }
static abstract class CacheManagerTestCustomizer<C extends CacheManager> static abstract class CacheManagerTestCustomizer<T extends CacheManager>
implements CacheManagerCustomizer<C> { implements CacheManagerCustomizer<T> {
private C cacheManager; private T cacheManager;
@Override @Override
public void customize(C cacheManager) { public void customize(T cacheManager) {
if (this.cacheManager != null) { if (this.cacheManager != null) {
throw new IllegalStateException("Customized invoked twice"); throw new IllegalStateException("Customized invoked twice");
} }
this.cacheManager = cacheManager; this.cacheManager = cacheManager;
} }
} }
} }
...@@ -38,7 +38,7 @@ import static org.mockito.Mockito.verifyZeroInteractions; ...@@ -38,7 +38,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
* *
* @author Stephane Nicoll * @author Stephane Nicoll
*/ */
public class CacheManagerCustomizerInvokerTests { public class CacheManagerCustomizersTests {
private AnnotationConfigApplicationContext context; private AnnotationConfigApplicationContext context;
...@@ -59,7 +59,7 @@ public class CacheManagerCustomizerInvokerTests { ...@@ -59,7 +59,7 @@ public class CacheManagerCustomizerInvokerTests {
@Test @Test
public void customizeNoConfigurableApplicationContext() { public void customizeNoConfigurableApplicationContext() {
CacheManagerCustomizerInvoker invoker = new CacheManagerCustomizerInvoker(); CacheManagerCustomizers invoker = new CacheManagerCustomizers();
ApplicationContext context = mock(ApplicationContext.class); ApplicationContext context = mock(ApplicationContext.class);
invoker.setApplicationContext(context); invoker.setApplicationContext(context);
invoker.customize(mock(CacheManager.class)); invoker.customize(mock(CacheManager.class));
...@@ -82,11 +82,14 @@ public class CacheManagerCustomizerInvokerTests { ...@@ -82,11 +82,14 @@ public class CacheManagerCustomizerInvokerTests {
@Bean @Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() { public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
return new CacheManagerCustomizer<ConcurrentMapCacheManager>() { return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
@Override @Override
public void customize(ConcurrentMapCacheManager cacheManager) { public void customize(ConcurrentMapCacheManager cacheManager) {
cacheManager.setCacheNames(Arrays.asList("one", "two")); cacheManager.setCacheNames(Arrays.asList("one", "two"));
} }
}; };
} }
} }
} }
...@@ -3280,6 +3280,7 @@ as you want and you can also order them as usual using `@Order` or `Ordered`. ...@@ -3280,6 +3280,7 @@ as you want and you can also order them as usual using `@Order` or `Ordered`.
=== ===
[[boot-features-caching-provider-generic]] [[boot-features-caching-provider-generic]]
==== Generic ==== Generic
Generic caching is used if the context defines _at least_ one Generic caching is used if the context defines _at least_ one
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment