Polish CacheManagerCustomizers

pull/5489/head
Phillip Webb 9 years ago
parent 7ba16e37e8
commit 4fd778fed8

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -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;
* 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 @@
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;
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 {
* {@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 {
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 {

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2015 the original author or authors. * Copyright 2012-2016 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -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;
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 {
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 {
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 {
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 {
} }
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 {
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 {
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 {
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 {
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 {
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 {
@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 {
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) {
@ -56,8 +56,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 {
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 {
if (!cacheNames.isEmpty()) { if (!cacheNames.isEmpty()) {
cacheManager.setCacheNames(cacheNames); cacheManager.setCacheNames(cacheNames);
} }
this.customizerInvoker.customize(cacheManager); return this.customizerInvoker.customize(cacheManager);
return cacheManager;
} }
} }

@ -473,7 +473,8 @@ 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(), containsInAnyOrder("foo", "bar")); assertThat(cacheManager.getCacheNames(), containsInAnyOrder("foo", "bar"));
assertThat(cacheManager.getCacheNames(), hasSize(2)); assertThat(cacheManager.getCacheNames(), hasSize(2));
} }
@ -921,18 +922,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;
} }
} }
} }

@ -40,7 +40,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;
@ -62,7 +62,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));
@ -85,11 +85,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"));
} }
}; };
} }
} }
} }

@ -3209,6 +3209,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

Loading…
Cancel
Save