Polish CacheManagerCustomizers

This commit is contained in:
Phillip Webb 2016-02-25 20:00:29 -08:00
parent 7ba16e37e8
commit 4fd778fed8
14 changed files with 58 additions and 52 deletions

View File

@ -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");
* you may not use this file except in compliance with the License.
@ -66,7 +66,7 @@ import org.springframework.util.Assert;
@EnableConfigurationProperties(CacheProperties.class)
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
@AutoConfigureAfter({ HazelcastAutoConfiguration.class, RedisAutoConfiguration.class })
@Import({ CacheManagerCustomizerInvoker.class, CacheConfigurationImportSelector.class })
@Import({ CacheManagerCustomizers.class, CacheConfigurationImportSelector.class })
public class CacheAutoConfiguration {
static final String VALIDATOR_BEAN_NAME = "cacheAutoConfigurationValidator";

View File

@ -22,16 +22,16 @@ import org.springframework.cache.CacheManager;
* 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.
*
* @param <C> The type of the {@link CacheManager}
* @param <T> The type of the {@link CacheManager}
* @author Stephane Nicoll
* @since 1.3.3
*/
public interface CacheManagerCustomizer<C extends CacheManager> {
public interface CacheManagerCustomizer<T extends CacheManager> {
/**
* Customize the cache manager.
* @param cacheManager the {@code CacheManager} to customize
*/
void customize(C cacheManager);
void customize(T cacheManager);
}

View File

@ -17,9 +17,9 @@
package org.springframework.boot.autoconfigure.cache;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactoryUtils;
@ -31,12 +31,12 @@ import org.springframework.core.GenericTypeResolver;
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}.
*
* @author Stephane Nicoll
*/
class CacheManagerCustomizerInvoker implements ApplicationContextAware {
class CacheManagerCustomizers implements ApplicationContextAware {
private ConfigurableApplicationContext applicationContext;
@ -45,14 +45,16 @@ class CacheManagerCustomizerInvoker implements ApplicationContextAware {
* {@link CacheManagerCustomizer} beans able to handle the specified instance and
* invoke {@link CacheManagerCustomizer#customize(CacheManager)} on them.
* @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(
cacheManager);
AnnotationAwareOrderComparator.sort(customizers);
for (CacheManagerCustomizer<CacheManager> customizer : customizers) {
customizer.customize(cacheManager);
}
return cacheManager;
}
@SuppressWarnings({ "unchecked", "rawtypes" })
@ -61,20 +63,28 @@ class CacheManagerCustomizerInvoker implements ApplicationContextAware {
if (this.applicationContext == null) {
return Collections.emptyList();
}
Map<String, CacheManagerCustomizer> map = BeanFactoryUtils
.beansOfTypeIncludingAncestors(this.applicationContext.getBeanFactory(),
CacheManagerCustomizer.class);
Class<?> cacheManagerClass = cacheManager.getClass();
List<CacheManagerCustomizer<CacheManager>> customizers = new ArrayList<CacheManagerCustomizer<CacheManager>>();
for (CacheManagerCustomizer customizer : map.values()) {
Class<?> target = GenericTypeResolver.resolveTypeArgument(
customizer.getClass(), CacheManagerCustomizer.class);
if (target == null || target.isAssignableFrom(cacheManager.getClass())) {
for (CacheManagerCustomizer customizer : getBeans(CacheManagerCustomizer.class)) {
if (canCustomize(customizer, cacheManagerClass)) {
customizers.add(customizer);
}
}
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
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {

View File

@ -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");
* you may not use this file except in compliance with the License.
@ -49,13 +49,11 @@ class EhCacheCacheConfiguration {
private CacheProperties cacheProperties;
@Autowired
CacheManagerCustomizerInvoker customizerInvoker;
private CacheManagerCustomizers customizers;
@Bean
public EhCacheCacheManager cacheManager(CacheManager ehCacheCacheManager) {
EhCacheCacheManager cacheManager = new EhCacheCacheManager(ehCacheCacheManager);
this.customizerInvoker.customize(cacheManager);
return cacheManager;
return this.customizers.customize(new EhCacheCacheManager(ehCacheCacheManager));
}
@Bean

View File

@ -42,14 +42,13 @@ import org.springframework.context.annotation.Configuration;
class GenericCacheConfiguration {
@Autowired
CacheManagerCustomizerInvoker customizerInvoker;
private CacheManagerCustomizers customizers;
@Bean
public SimpleCacheManager cacheManager(Collection<Cache> caches) {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(caches);
this.customizerInvoker.customize(cacheManager);
return cacheManager;
return this.customizers.customize(cacheManager);
}
}

View File

@ -49,7 +49,7 @@ class GuavaCacheConfiguration {
private CacheProperties cacheProperties;
@Autowired
CacheManagerCustomizerInvoker customizerInvoker;
private CacheManagerCustomizers customizers;
@Autowired(required = false)
private CacheBuilder<Object, Object> cacheBuilder;
@ -67,8 +67,7 @@ class GuavaCacheConfiguration {
if (!CollectionUtils.isEmpty(cacheNames)) {
cacheManager.setCacheNames(cacheNames);
}
this.customizerInvoker.customize(cacheManager);
return cacheManager;
return this.customizers.customize(cacheManager);
}
private GuavaCacheManager createCacheManager() {

View File

@ -49,7 +49,7 @@ abstract class HazelcastInstanceConfiguration {
private CacheProperties cacheProperties;
@Autowired
CacheManagerCustomizerInvoker customizerInvoker;
private CacheManagerCustomizers customizers;
@Bean
public HazelcastCacheManager cacheManager(
@ -63,8 +63,7 @@ abstract class HazelcastInstanceConfiguration {
}
HazelcastCacheManager cacheManager = new HazelcastCacheManager(
existingHazelcastInstance);
this.customizerInvoker.customize(cacheManager);
return cacheManager;
return this.customizers.customize(cacheManager);
}
}
@ -77,7 +76,7 @@ abstract class HazelcastInstanceConfiguration {
private CacheProperties cacheProperties;
@Autowired
CacheManagerCustomizerInvoker customizerInvoker;
private CacheManagerCustomizers customizers;
@Bean
public HazelcastInstance hazelcastInstance() throws IOException {
@ -93,8 +92,7 @@ abstract class HazelcastInstanceConfiguration {
public HazelcastCacheManager cacheManager() throws IOException {
HazelcastCacheManager cacheManager = new HazelcastCacheManager(
hazelcastInstance());
this.customizerInvoker.customize(cacheManager);
return cacheManager;
return this.customizers.customize(cacheManager);
}
}

View File

@ -52,7 +52,7 @@ public class InfinispanCacheConfiguration {
private CacheProperties cacheProperties;
@Autowired
CacheManagerCustomizerInvoker customizerInvoker;
private CacheManagerCustomizers customizers;
@Autowired(required = false)
private ConfigurationBuilder defaultConfigurationBuilder;
@ -62,8 +62,7 @@ public class InfinispanCacheConfiguration {
EmbeddedCacheManager embeddedCacheManager) {
SpringEmbeddedCacheManager cacheManager = new SpringEmbeddedCacheManager(
embeddedCacheManager);
this.customizerInvoker.customize(cacheManager);
return cacheManager;
return this.customizers.customize(cacheManager);
}
@Bean(destroyMethod = "stop")

View File

@ -64,7 +64,7 @@ class JCacheCacheConfiguration {
private CacheProperties cacheProperties;
@Autowired
CacheManagerCustomizerInvoker customizerInvoker;
private CacheManagerCustomizers customizers;
@Autowired(required = false)
private javax.cache.configuration.Configuration<?, ?> defaultCacheConfiguration;
@ -75,8 +75,7 @@ class JCacheCacheConfiguration {
@Bean
public JCacheCacheManager cacheManager(CacheManager jCacheCacheManager) {
JCacheCacheManager cacheManager = new JCacheCacheManager(jCacheCacheManager);
this.customizerInvoker.customize(cacheManager);
return cacheManager;
return this.customizers.customize(cacheManager);
}
@Bean

View File

@ -47,7 +47,7 @@ class RedisCacheConfiguration {
private CacheProperties cacheProperties;
@Autowired
CacheManagerCustomizerInvoker customizerInvoker;
private CacheManagerCustomizers customizerInvoker;
@Bean
public RedisCacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) {
@ -56,8 +56,7 @@ class RedisCacheConfiguration {
if (!cacheNames.isEmpty()) {
cacheManager.setCacheNames(cacheNames);
}
this.customizerInvoker.customize(cacheManager);
return cacheManager;
return this.customizerInvoker.customize(cacheManager);
}
}

View File

@ -41,7 +41,7 @@ class SimpleCacheConfiguration {
private CacheProperties cacheProperties;
@Autowired
CacheManagerCustomizerInvoker customizerInvoker;
private CacheManagerCustomizers customizerInvoker;
@Bean
public ConcurrentMapCacheManager cacheManager() {
@ -50,8 +50,7 @@ class SimpleCacheConfiguration {
if (!cacheNames.isEmpty()) {
cacheManager.setCacheNames(cacheNames);
}
this.customizerInvoker.customize(cacheManager);
return cacheManager;
return this.customizerInvoker.customize(cacheManager);
}
}

View File

@ -473,7 +473,8 @@ public class CacheAutoConfigurationTests {
load(DefaultCacheConfiguration.class, "spring.cache.type=jcache",
"spring.cache.jcache.provider=" + cachingProviderFqn,
"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(), hasSize(2));
}
@ -921,18 +922,19 @@ public class CacheAutoConfigurationTests {
}
static abstract class CacheManagerTestCustomizer<C extends CacheManager>
implements CacheManagerCustomizer<C> {
static abstract class CacheManagerTestCustomizer<T extends CacheManager>
implements CacheManagerCustomizer<T> {
private C cacheManager;
private T cacheManager;
@Override
public void customize(C cacheManager) {
public void customize(T cacheManager) {
if (this.cacheManager != null) {
throw new IllegalStateException("Customized invoked twice");
}
this.cacheManager = cacheManager;
}
}
}

View File

@ -40,7 +40,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
*
* @author Stephane Nicoll
*/
public class CacheManagerCustomizerInvokerTests {
public class CacheManagerCustomizersTests {
private AnnotationConfigApplicationContext context;
@ -62,7 +62,7 @@ public class CacheManagerCustomizerInvokerTests {
@Test
public void customizeNoConfigurableApplicationContext() {
CacheManagerCustomizerInvoker invoker = new CacheManagerCustomizerInvoker();
CacheManagerCustomizers invoker = new CacheManagerCustomizers();
ApplicationContext context = mock(ApplicationContext.class);
invoker.setApplicationContext(context);
invoker.customize(mock(CacheManager.class));
@ -85,11 +85,14 @@ public class CacheManagerCustomizerInvokerTests {
@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
@Override
public void customize(ConcurrentMapCacheManager cacheManager) {
cacheManager.setCacheNames(Arrays.asList("one", "two"));
}
};
}
}
}

View File

@ -3209,6 +3209,7 @@ as you want and you can also order them as usual using `@Order` or `Ordered`.
===
[[boot-features-caching-provider-generic]]
==== Generic
Generic caching is used if the context defines _at least_ one