Use spring.cache.config with JCache
According to the spec, specifying a custom URI when retrieving a `javax.cache.CacheManager` might be used as a way to transmit the location of a custom configuration file to initialize the underlying cache manager. If `spring.cache.config` is set, we use that information to retrieve a CacheManager with that configuration file. Unfortunately, hazelcast does not support this feature so we are setting the property key it expects instead. See https://github.com/hazelcast/hazelcast/issues/4943 Closes gh-2743
This commit is contained in:
@@ -16,8 +16,10 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import javax.cache.CacheManager;
|
||||
import javax.cache.Caching;
|
||||
import javax.cache.configuration.MutableConfiguration;
|
||||
@@ -37,6 +39,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.type.AnnotatedTypeMetadata;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -64,9 +67,8 @@ class JCacheCacheConfiguration {
|
||||
private List<JCacheManagerCustomizer> cacheManagerCustomizers;
|
||||
|
||||
@Bean
|
||||
public JCacheCacheManager cacheManager() {
|
||||
CacheManager cacheManager = createCacheManager(this.cacheProperties.getJcache()
|
||||
.getProvider());
|
||||
public JCacheCacheManager cacheManager() throws IOException {
|
||||
CacheManager cacheManager = createCacheManager();
|
||||
List<String> cacheNames = this.cacheProperties.getCacheNames();
|
||||
if (!CollectionUtils.isEmpty(cacheNames)) {
|
||||
for (String cacheName : cacheNames) {
|
||||
@@ -77,11 +79,29 @@ class JCacheCacheConfiguration {
|
||||
return new JCacheCacheManager(cacheManager);
|
||||
}
|
||||
|
||||
private CacheManager createCacheManager(String cachingProvider) {
|
||||
if (StringUtils.hasText(cachingProvider)) {
|
||||
return Caching.getCachingProvider(cachingProvider).getCacheManager();
|
||||
private CacheManager createCacheManager() throws IOException {
|
||||
CachingProvider cachingProvider = getCachingProvider(this.cacheProperties
|
||||
.getJcache().getProvider());
|
||||
Resource configLocation = this.cacheProperties.resolveConfigLocation();
|
||||
if (configLocation != null) {
|
||||
return cachingProvider.getCacheManager(configLocation.getURI(),
|
||||
cachingProvider.getDefaultClassLoader(), createCacheManagerProperties(configLocation));
|
||||
}
|
||||
return Caching.getCachingProvider().getCacheManager();
|
||||
return cachingProvider.getCacheManager();
|
||||
}
|
||||
|
||||
private CachingProvider getCachingProvider(String cachingProviderFqn) {
|
||||
if (StringUtils.hasText(cachingProviderFqn)) {
|
||||
return Caching.getCachingProvider(cachingProviderFqn);
|
||||
}
|
||||
return Caching.getCachingProvider();
|
||||
}
|
||||
|
||||
private Properties createCacheManagerProperties(Resource configLocation) throws IOException {
|
||||
Properties properties = new Properties();
|
||||
// Hazelcast does not use the URI as a mean to specify a custom config.
|
||||
properties.setProperty("hazelcast.config.location", configLocation.getURI().toString());
|
||||
return properties;
|
||||
}
|
||||
|
||||
private javax.cache.configuration.Configuration<?, ?> getDefaultCacheConfiguration() {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
@@ -50,6 +51,8 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
|
||||
@@ -250,6 +253,30 @@ public class CacheAutoConfigurationTests {
|
||||
"spring.cache.jcache.provider=" + wrongCachingProviderFqn);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jCacheCacheWithConfig() throws IOException {
|
||||
String cachingProviderFqn = MockCachingProvider.class.getName();
|
||||
String configLocation = "org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml";
|
||||
load(JCacheCustomConfiguration.class, "spring.cache.type=jcache",
|
||||
"spring.cache.jcache.provider=" + cachingProviderFqn,
|
||||
"spring.cache.config=" + configLocation);
|
||||
JCacheCacheManager cacheManager = validateCacheManager(JCacheCacheManager.class);
|
||||
Resource configResource = new ClassPathResource(configLocation);
|
||||
assertThat(cacheManager.getCacheManager().getURI(), is(configResource.getURI()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jCacheCacheWithWrongConfig() {
|
||||
String cachingProviderFqn = MockCachingProvider.class.getName();
|
||||
String configLocation = "org/springframework/boot/autoconfigure/cache/does-not-exist.xml";
|
||||
thrown.expect(BeanCreationException.class);
|
||||
thrown.expectMessage("spring.cache.config");
|
||||
thrown.expectMessage(configLocation);
|
||||
load(JCacheCustomConfiguration.class, "spring.cache.type=jcache",
|
||||
"spring.cache.jcache.provider=" + cachingProviderFqn,
|
||||
"spring.cache.config=" + configLocation);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ehCacheCacheWithCaches() {
|
||||
load(DefaultCacheConfiguration.class, "spring.cache.type=ehcache");
|
||||
@@ -268,7 +295,7 @@ public class CacheAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ehCacheCacheWithLocation() {
|
||||
public void ehCacheCacheWithConfig() {
|
||||
load(DefaultCacheConfiguration.class, "spring.cache.type=ehcache",
|
||||
"spring.cache.config=cache/ehcache-override.xml");
|
||||
EhCacheCacheManager cacheManager = null;
|
||||
@@ -296,7 +323,7 @@ public class CacheAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hazelcastCacheWithLocation() {
|
||||
public void hazelcastCacheWithConfig() {
|
||||
load(DefaultCacheConfiguration.class, "spring.cache.type=hazelcast",
|
||||
"spring.cache.config=org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml");
|
||||
HazelcastCacheManager cacheManager = validateCacheManager(HazelcastCacheManager.class);
|
||||
@@ -306,12 +333,11 @@ public class CacheAutoConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hazelcastWithWrongLocation() {
|
||||
public void hazelcastWithWrongConfig() {
|
||||
this.thrown.expect(BeanCreationException.class);
|
||||
this.thrown.expectMessage("foo/bar/unknown.xml");
|
||||
load(DefaultCacheConfiguration.class, "spring.cache.type=hazelcast",
|
||||
"spring.cache.config=foo/bar/unknown.xml");
|
||||
System.out.println(this.context.getBean(CacheManager.class).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -333,6 +359,27 @@ public class CacheAutoConfigurationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hazelcastAsJCacheWithConfig() throws IOException {
|
||||
String cachingProviderFqn = HazelcastCachingProvider.class.getName();
|
||||
String configLocation = "org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml";
|
||||
JCacheCacheManager cacheManager = null;
|
||||
try {
|
||||
load(DefaultCacheConfiguration.class, "spring.cache.type=jcache",
|
||||
"spring.cache.jcache.provider=" + cachingProviderFqn,
|
||||
"spring.cache.config="+configLocation);
|
||||
cacheManager = validateCacheManager(JCacheCacheManager.class);
|
||||
|
||||
Resource configResource = new ClassPathResource(configLocation);
|
||||
assertThat(cacheManager.getCacheManager().getURI(), is(configResource.getURI()));
|
||||
}
|
||||
finally {
|
||||
if (cacheManager != null) {
|
||||
cacheManager.getCacheManager().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jCacheCacheWithCachesAndCustomizer() {
|
||||
String cachingProviderFqn = HazelcastCachingProvider.class.getName();
|
||||
|
||||
@@ -48,6 +48,8 @@ public class MockCachingProvider implements CachingProvider {
|
||||
public CacheManager getCacheManager(URI uri, ClassLoader classLoader,
|
||||
Properties properties) {
|
||||
CacheManager cacheManager = mock(CacheManager.class);
|
||||
given(cacheManager.getURI()).willReturn(uri);
|
||||
given(cacheManager.getClassLoader()).willReturn(classLoader);
|
||||
final Map<String, Cache> caches = new HashMap<String, Cache>();
|
||||
given(cacheManager.getCacheNames()).willReturn(caches.keySet());
|
||||
given(cacheManager.getCache(anyString())).willAnswer(new Answer<Cache>() {
|
||||
@@ -74,7 +76,7 @@ public class MockCachingProvider implements CachingProvider {
|
||||
|
||||
@Override
|
||||
public ClassLoader getDefaultClassLoader() {
|
||||
return null;
|
||||
return mock(ClassLoader.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user