Skip to content

Commit 5febd49

Browse files
committed
Support customization of CacheManager
This commit allows to customize the auto-configured `CacheManager` by exposing a bean of type `CacheManagerCustomizer`. The implementation may reference the type of a `CacheManager` to determine in which case it has to be invoked. Several implementations can be provided and ordered using the regular `Ordered` interface and `@Order` annotation. Closes gh-5039
1 parent ce71bd9 commit 5febd49

14 files changed

+445
-17
lines changed

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/CacheAutoConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
@EnableConfigurationProperties(CacheProperties.class)
6767
@AutoConfigureBefore(HibernateJpaAutoConfiguration.class)
6868
@AutoConfigureAfter({ HazelcastAutoConfiguration.class, RedisAutoConfiguration.class })
69-
@Import(CacheConfigurationImportSelector.class)
69+
@Import({ CacheManagerCustomizerInvoker.class, CacheConfigurationImportSelector.class })
7070
public class CacheAutoConfiguration {
7171

7272
static final String VALIDATOR_BEAN_NAME = "cacheAutoConfigurationValidator";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.cache;
18+
19+
import org.springframework.cache.CacheManager;
20+
21+
/**
22+
* Callback interface that can be implemented by beans wishing to customize the cache
23+
* manager before it is fully initialized, in particular to tune its configuration.
24+
*
25+
* @author Stephane Nicoll
26+
* @since 1.3.3
27+
*/
28+
public interface CacheManagerCustomizer<C extends CacheManager> {
29+
30+
/**
31+
* Customize the cache manager.
32+
* @param cacheManager the {@code CacheManager} to customize
33+
*/
34+
void customize(C cacheManager);
35+
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
* Copyright 2012-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.cache;
18+
19+
import java.util.ArrayList;
20+
import java.util.Collections;
21+
import java.util.List;
22+
import java.util.Map;
23+
24+
import org.springframework.beans.BeansException;
25+
import org.springframework.beans.factory.BeanFactoryUtils;
26+
import org.springframework.cache.CacheManager;
27+
import org.springframework.context.ApplicationContext;
28+
import org.springframework.context.ApplicationContextAware;
29+
import org.springframework.context.ConfigurableApplicationContext;
30+
import org.springframework.core.GenericTypeResolver;
31+
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
32+
33+
/**
34+
* Invoke the available {@link CacheManagerCustomizer} instances in the context for a
35+
* given {@link CacheManager}.
36+
*
37+
* @author Stephane Nicoll
38+
*/
39+
class CacheManagerCustomizerInvoker implements ApplicationContextAware {
40+
41+
private ConfigurableApplicationContext applicationContext;
42+
43+
/**
44+
* Customize the specified {@link CacheManager}. Locates all {@link CacheManagerCustomizer}
45+
* beans able to handle the specified instance and invoke
46+
* {@link CacheManagerCustomizer#customize(CacheManager)} on them.
47+
* @param cacheManager the cache manager to customize
48+
*/
49+
public void customize(CacheManager cacheManager) {
50+
List<CacheManagerCustomizer<CacheManager>> customizers = findCustomizers(cacheManager);
51+
AnnotationAwareOrderComparator.sort(customizers);
52+
for (CacheManagerCustomizer<CacheManager> customizer : customizers) {
53+
customizer.customize(cacheManager);
54+
}
55+
}
56+
57+
@SuppressWarnings("unchecked")
58+
private List<CacheManagerCustomizer<CacheManager>> findCustomizers(CacheManager cacheManager) {
59+
if (this.applicationContext == null) {
60+
return Collections.emptyList();
61+
}
62+
Map<String, CacheManagerCustomizer> map = BeanFactoryUtils
63+
.beansOfTypeIncludingAncestors(this.applicationContext.getBeanFactory(), CacheManagerCustomizer.class);
64+
List<CacheManagerCustomizer<CacheManager>> customizers
65+
= new ArrayList<CacheManagerCustomizer<CacheManager>>();
66+
for (CacheManagerCustomizer customizer : map.values()) {
67+
Class<?> target = GenericTypeResolver.resolveTypeArgument(
68+
customizer.getClass(), CacheManagerCustomizer.class);
69+
if (target == null || target.isAssignableFrom(cacheManager.getClass())) {
70+
customizers.add(customizer);
71+
}
72+
}
73+
return customizers;
74+
}
75+
76+
77+
@Override
78+
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
79+
if (applicationContext instanceof ConfigurableApplicationContext) {
80+
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
81+
}
82+
}
83+
84+
}

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/EhCacheCacheConfiguration.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,14 @@ class EhCacheCacheConfiguration {
4848
@Autowired
4949
private CacheProperties cacheProperties;
5050

51+
@Autowired
52+
CacheManagerCustomizerInvoker customizerInvoker;
53+
5154
@Bean
5255
public EhCacheCacheManager cacheManager(CacheManager ehCacheCacheManager) {
53-
return new EhCacheCacheManager(ehCacheCacheManager);
56+
EhCacheCacheManager cacheManager = new EhCacheCacheManager(ehCacheCacheManager);
57+
this.customizerInvoker.customize(cacheManager);
58+
return cacheManager;
5459
}
5560

5661
@Bean

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/GenericCacheConfiguration.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.util.Collection;
2020

21+
import org.springframework.beans.factory.annotation.Autowired;
2122
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2223
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
2324
import org.springframework.cache.Cache;
@@ -40,10 +41,14 @@
4041
@Conditional(CacheCondition.class)
4142
class GenericCacheConfiguration {
4243

44+
@Autowired
45+
CacheManagerCustomizerInvoker customizerInvoker;
46+
4347
@Bean
4448
public SimpleCacheManager cacheManager(Collection<Cache> caches) {
4549
SimpleCacheManager cacheManager = new SimpleCacheManager();
4650
cacheManager.setCaches(caches);
51+
this.customizerInvoker.customize(cacheManager);
4752
return cacheManager;
4853
}
4954

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/GuavaCacheConfiguration.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -48,6 +48,9 @@ class GuavaCacheConfiguration {
4848
@Autowired
4949
private CacheProperties cacheProperties;
5050

51+
@Autowired
52+
CacheManagerCustomizerInvoker customizerInvoker;
53+
5154
@Autowired(required = false)
5255
private CacheBuilder<Object, Object> cacheBuilder;
5356

@@ -64,6 +67,7 @@ public GuavaCacheManager cacheManager() {
6467
if (!CollectionUtils.isEmpty(cacheNames)) {
6568
cacheManager.setCacheNames(cacheNames);
6669
}
70+
this.customizerInvoker.customize(cacheManager);
6771
return cacheManager;
6872
}
6973

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/HazelcastInstanceConfiguration.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ static class Existing {
4848
@Autowired
4949
private CacheProperties cacheProperties;
5050

51+
@Autowired
52+
CacheManagerCustomizerInvoker customizerInvoker;
53+
5154
@Bean
5255
public HazelcastCacheManager cacheManager(
5356
HazelcastInstance existingHazelcastInstance) throws IOException {
@@ -58,7 +61,9 @@ public HazelcastCacheManager cacheManager(
5861
location).getHazelcastInstance();
5962
return new CloseableHazelcastCacheManager(cacheHazelcastInstance);
6063
}
61-
return new HazelcastCacheManager(existingHazelcastInstance);
64+
HazelcastCacheManager cacheManager = new HazelcastCacheManager(existingHazelcastInstance);
65+
this.customizerInvoker.customize(cacheManager);
66+
return cacheManager;
6267
}
6368
}
6469

@@ -70,6 +75,9 @@ static class Specific {
7075
@Autowired
7176
private CacheProperties cacheProperties;
7277

78+
@Autowired
79+
CacheManagerCustomizerInvoker customizerInvoker;
80+
7381
@Bean
7482
public HazelcastInstance hazelcastInstance() throws IOException {
7583
Resource config = this.cacheProperties.getHazelcast().getConfig();
@@ -82,7 +90,9 @@ public HazelcastInstance hazelcastInstance() throws IOException {
8290

8391
@Bean
8492
public HazelcastCacheManager cacheManager() throws IOException {
85-
return new HazelcastCacheManager(hazelcastInstance());
93+
HazelcastCacheManager cacheManager = new HazelcastCacheManager(hazelcastInstance());
94+
this.customizerInvoker.customize(cacheManager);
95+
return cacheManager;
8696
}
8797

8898
}

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/InfinispanCacheConfiguration.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -51,13 +51,18 @@ public class InfinispanCacheConfiguration {
5151
@Autowired
5252
private CacheProperties cacheProperties;
5353

54+
@Autowired
55+
CacheManagerCustomizerInvoker customizerInvoker;
56+
5457
@Autowired(required = false)
5558
private ConfigurationBuilder defaultConfigurationBuilder;
5659

5760
@Bean
5861
public SpringEmbeddedCacheManager cacheManager(
5962
EmbeddedCacheManager embeddedCacheManager) {
60-
return new SpringEmbeddedCacheManager(embeddedCacheManager);
63+
SpringEmbeddedCacheManager cacheManager = new SpringEmbeddedCacheManager(embeddedCacheManager);
64+
this.customizerInvoker.customize(cacheManager);
65+
return cacheManager;
6166
}
6267

6368
@Bean(destroyMethod = "stop")

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/JCacheCacheConfiguration.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -63,6 +63,9 @@ class JCacheCacheConfiguration {
6363
@Autowired
6464
private CacheProperties cacheProperties;
6565

66+
@Autowired
67+
CacheManagerCustomizerInvoker customizerInvoker;
68+
6669
@Autowired(required = false)
6770
private javax.cache.configuration.Configuration<?, ?> defaultCacheConfiguration;
6871

@@ -71,7 +74,9 @@ class JCacheCacheConfiguration {
7174

7275
@Bean
7376
public JCacheCacheManager cacheManager(CacheManager jCacheCacheManager) {
74-
return new JCacheCacheManager(jCacheCacheManager);
77+
JCacheCacheManager cacheManager = new JCacheCacheManager(jCacheCacheManager);
78+
this.customizerInvoker.customize(cacheManager);
79+
return cacheManager;
7580
}
7681

7782
@Bean

spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/cache/RedisCacheConfiguration.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -46,13 +46,17 @@ class RedisCacheConfiguration {
4646
@Autowired
4747
private CacheProperties cacheProperties;
4848

49+
@Autowired
50+
CacheManagerCustomizerInvoker customizerInvoker;
51+
4952
@Bean
5053
public RedisCacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) {
5154
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
5255
List<String> cacheNames = this.cacheProperties.getCacheNames();
5356
if (!cacheNames.isEmpty()) {
5457
cacheManager.setCacheNames(cacheNames);
5558
}
59+
this.customizerInvoker.customize(cacheManager);
5660
return cacheManager;
5761
}
5862

0 commit comments

Comments
 (0)