Polish cache code

pull/3115/head
Phillip Webb 10 years ago
parent 412b7b9e50
commit d2f11c465e

@ -18,11 +18,9 @@ package org.springframework.boot.actuate.autoconfigure;
import javax.cache.Caching; import javax.cache.Caching;
import com.hazelcast.core.IMap;
import com.hazelcast.spring.cache.HazelcastCache;
import net.sf.ehcache.Ehcache; import net.sf.ehcache.Ehcache;
import org.infinispan.spring.provider.SpringCache;
import org.infinispan.spring.provider.SpringCache;
import org.springframework.boot.actuate.cache.CacheStatistics; import org.springframework.boot.actuate.cache.CacheStatistics;
import org.springframework.boot.actuate.cache.CacheStatisticsProvider; import org.springframework.boot.actuate.cache.CacheStatisticsProvider;
import org.springframework.boot.actuate.cache.ConcurrentMapCacheStatisticsProvider; import org.springframework.boot.actuate.cache.ConcurrentMapCacheStatisticsProvider;
@ -45,6 +43,9 @@ import org.springframework.cache.support.NoOpCacheManager;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import com.hazelcast.core.IMap;
import com.hazelcast.spring.cache.HazelcastCache;
/** /**
* {@link EnableAutoConfiguration Auto-configuration} for {@link CacheStatisticsProvider} * {@link EnableAutoConfiguration Auto-configuration} for {@link CacheStatisticsProvider}
* beans. * beans.

@ -19,6 +19,7 @@ package org.springframework.boot.actuate.cache;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.management.AttributeNotFoundException; import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException; import javax.management.InstanceNotFoundException;
import javax.management.MBeanException; import javax.management.MBeanException;
@ -29,37 +30,32 @@ import javax.management.ReflectionException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager; import org.springframework.cache.CacheManager;
/** /**
* Base {@link CacheStatisticsProvider} implementation that uses JMX to * Base {@link CacheStatisticsProvider} implementation that uses JMX to retrieve the cache
* retrieve the cache statistics. * statistics.
* *
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.0 * @since 1.3.0
* @param <C> The cache type
*/ */
public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache> public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache> implements
implements CacheStatisticsProvider<C> { CacheStatisticsProvider<C> {
private static final Logger logger = LoggerFactory private static final Logger logger = LoggerFactory
.getLogger(AbstractJmxCacheStatisticsProvider.class); .getLogger(AbstractJmxCacheStatisticsProvider.class);
private MBeanServer mBeanServer; private MBeanServer mBeanServer;
private Map<String, ObjectNameWrapper> caches = private Map<String, ObjectNameWrapper> caches = new ConcurrentHashMap<String, ObjectNameWrapper>();
new ConcurrentHashMap<String, ObjectNameWrapper>();
@Override @Override
public CacheStatistics getCacheStatistics(CacheManager cacheManager, C cache) { public CacheStatistics getCacheStatistics(CacheManager cacheManager, C cache) {
try { try {
ObjectName objectName = internalGetObjectName(cache); ObjectName objectName = internalGetObjectName(cache);
if (objectName != null) { return (objectName == null ? null : getCacheStatistics(objectName));
return getCacheStatistics(objectName);
}
return null;
} }
catch (MalformedObjectNameException ex) { catch (MalformedObjectNameException ex) {
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
@ -71,20 +67,20 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
* {@code null} if none is found. * {@code null} if none is found.
* @param cache the cache to handle * @param cache the cache to handle
* @return the object name of the cache statistics MBean * @return the object name of the cache statistics MBean
* @throws MalformedObjectNameException
*/ */
protected abstract ObjectName getObjectName(C cache) throws MalformedObjectNameException; protected abstract ObjectName getObjectName(C cache)
throws MalformedObjectNameException;
/** /**
* Return the current {@link CacheStatistics} snapshot from the MBean identified by the * Return the current {@link CacheStatistics} snapshot from the MBean identified by
* specified {@link ObjectName}. * the specified {@link ObjectName}.
* @param objectName the object name of the cache statistics MBean * @param objectName the object name of the cache statistics MBean
* @return the current cache statistics * @return the current cache statistics
*/ */
protected abstract CacheStatistics getCacheStatistics(ObjectName objectName); protected abstract CacheStatistics getCacheStatistics(ObjectName objectName);
private ObjectName internalGetObjectName(C cache) throws MalformedObjectNameException {
private ObjectName internalGetObjectName(C cache)
throws MalformedObjectNameException {
String cacheName = cache.getName(); String cacheName = cache.getName();
ObjectNameWrapper value = this.caches.get(cacheName); ObjectNameWrapper value = this.caches.get(cacheName);
if (value != null) { if (value != null) {
@ -102,7 +98,8 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
return this.mBeanServer; return this.mBeanServer;
} }
protected <T> T getAttribute(ObjectName objectName, String attributeName, Class<T> type) { protected <T> T getAttribute(ObjectName objectName, String attributeName,
Class<T> type) {
try { try {
Object attribute = getMBeanServer().getAttribute(objectName, attributeName); Object attribute = getMBeanServer().getAttribute(objectName, attributeName);
return type.cast(attribute); return type.cast(attribute);
@ -111,8 +108,8 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
} }
catch (AttributeNotFoundException ex) { catch (AttributeNotFoundException ex) {
throw new IllegalStateException("Unexpected: MBean with name '" + objectName + "' " + throw new IllegalStateException("Unexpected: MBean with name '" + objectName
"does not expose attribute with name " + attributeName, ex); + "' " + "does not expose attribute with name " + attributeName, ex);
} }
catch (ReflectionException ex) { catch (ReflectionException ex) {
throw new IllegalStateException(ex); throw new IllegalStateException(ex);
@ -123,13 +120,14 @@ public abstract class AbstractJmxCacheStatisticsProvider<C extends Cache>
} }
} }
private static class ObjectNameWrapper { private static class ObjectNameWrapper {
private final ObjectName objectName; private final ObjectName objectName;
public ObjectNameWrapper(ObjectName objectName) { public ObjectNameWrapper(ObjectName objectName) {
this.objectName = objectName; this.objectName = objectName;
} }
} }
} }

@ -86,4 +86,5 @@ public class DefaultCacheStatistics implements CacheStatistics {
metrics.add(new Metric<T>(name, value)); metrics.add(new Metric<T>(name, value));
} }
} }
} }

@ -17,6 +17,7 @@
package org.springframework.boot.actuate.cache; package org.springframework.boot.actuate.cache;
import java.util.Set; import java.util.Set;
import javax.management.MalformedObjectNameException; import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance; import javax.management.ObjectInstance;
import javax.management.ObjectName; import javax.management.ObjectName;
@ -29,35 +30,43 @@ import org.infinispan.spring.provider.SpringCache;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.0 * @since 1.3.0
*/ */
public class InfinispanCacheStatisticsProvider extends AbstractJmxCacheStatisticsProvider<SpringCache> { public class InfinispanCacheStatisticsProvider extends
AbstractJmxCacheStatisticsProvider<SpringCache> {
@Override @Override
protected ObjectName getObjectName(SpringCache cache) throws MalformedObjectNameException { protected ObjectName getObjectName(SpringCache cache)
Set<ObjectInstance> instances = getMBeanServer().queryMBeans( throws MalformedObjectNameException {
new ObjectName("org.infinispan:component=Statistics,type=Cache," + ObjectName name = new ObjectName(
"name=\"" + cache.getName() + "(local)\",*"), null); "org.infinispan:component=Statistics,type=Cache,name=\""
+ cache.getName() + "(local)\",*");
Set<ObjectInstance> instances = getMBeanServer().queryMBeans(name, null);
if (instances.size() == 1) { if (instances.size() == 1) {
return instances.iterator().next().getObjectName(); return instances.iterator().next().getObjectName();
} }
return null; // None or more than one // None or more than one
return null;
} }
@Override
protected CacheStatistics getCacheStatistics(ObjectName objectName) { protected CacheStatistics getCacheStatistics(ObjectName objectName) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics(); DefaultCacheStatistics statistics = new DefaultCacheStatistics();
Integer size = getAttribute(objectName, "numberOfEntries", Integer size = getAttribute(objectName, "numberOfEntries", Integer.class);
Integer.class);
if (size != null) { if (size != null) {
statistics.setSize((long) size); statistics.setSize((long) size);
if (size > 0) { // Let's initialize the stats if we have some data if (size > 0) {
Double hitRatio = getAttribute(objectName, "hitRatio", // Let's initialize the stats if we have some data
Double.class); initalizeStats(objectName, statistics);
}
}
return statistics;
}
private void initalizeStats(ObjectName objectName, DefaultCacheStatistics statistics) {
Double hitRatio = getAttribute(objectName, "hitRatio", Double.class);
if ((hitRatio != null)) { if ((hitRatio != null)) {
statistics.setHitRatio(hitRatio); statistics.setHitRatio(hitRatio);
statistics.setMissRatio(1 - hitRatio); statistics.setMissRatio(1 - hitRatio);
} }
} }
}
return statistics;
}
} }

@ -17,6 +17,7 @@
package org.springframework.boot.actuate.cache; package org.springframework.boot.actuate.cache;
import java.util.Set; import java.util.Set;
import javax.management.MalformedObjectNameException; import javax.management.MalformedObjectNameException;
import javax.management.ObjectInstance; import javax.management.ObjectInstance;
import javax.management.ObjectName; import javax.management.ObjectName;
@ -29,27 +30,28 @@ import org.springframework.cache.jcache.JCacheCache;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 1.3.0 * @since 1.3.0
*/ */
public class JCacheCacheStatisticsProvider extends AbstractJmxCacheStatisticsProvider<JCacheCache> { public class JCacheCacheStatisticsProvider extends
AbstractJmxCacheStatisticsProvider<JCacheCache> {
@Override
protected ObjectName getObjectName(JCacheCache cache) protected ObjectName getObjectName(JCacheCache cache)
throws MalformedObjectNameException { throws MalformedObjectNameException {
ObjectName name = new ObjectName("javax.cache:type=CacheStatistics,Cache="
Set<ObjectInstance> instances = getMBeanServer().queryMBeans( + cache.getName() + ",*");
new ObjectName("javax.cache:type=CacheStatistics,Cache=" Set<ObjectInstance> instances = getMBeanServer().queryMBeans(name, null);
+ cache.getName() + ",*"), null);
if (instances.size() == 1) { if (instances.size() == 1) {
return instances.iterator().next().getObjectName(); return instances.iterator().next().getObjectName();
} }
return null; // None or more than one // None or more than one
return null;
} }
@Override
protected CacheStatistics getCacheStatistics(ObjectName objectName) { protected CacheStatistics getCacheStatistics(ObjectName objectName) {
DefaultCacheStatistics statistics = new DefaultCacheStatistics(); DefaultCacheStatistics statistics = new DefaultCacheStatistics();
Float hitPercentage = getAttribute(objectName, "CacheHitPercentage", Float hitPercentage = getAttribute(objectName, "CacheHitPercentage", Float.class);
Float missPercentage = getAttribute(objectName, "CacheMissPercentage",
Float.class); Float.class);
Float missPercentage = getAttribute(objectName,
"CacheMissPercentage", Float.class);
if ((hitPercentage != null && missPercentage != null) if ((hitPercentage != null && missPercentage != null)
&& (hitPercentage > 0 || missPercentage > 0)) { && (hitPercentage > 0 || missPercentage > 0)) {
statistics.setHitRatio(hitPercentage / (double) 100); statistics.setHitRatio(hitPercentage / (double) 100);

@ -19,22 +19,15 @@ package org.springframework.boot.actuate.autoconfigure;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Arrays; import java.util.Arrays;
import javax.cache.Caching; import javax.cache.Caching;
import javax.cache.configuration.MutableConfiguration; import javax.cache.configuration.MutableConfiguration;
import com.google.common.cache.CacheBuilder;
import com.hazelcast.cache.HazelcastCachingProvider;
import com.hazelcast.config.Config;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.spring.cache.HazelcastCacheManager;
import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.spring.provider.SpringEmbeddedCacheManager; import org.infinispan.spring.provider.SpringEmbeddedCacheManager;
import org.junit.After; import org.junit.After;
import org.junit.Test; import org.junit.Test;
import org.springframework.boot.actuate.cache.CacheStatistics; import org.springframework.boot.actuate.cache.CacheStatistics;
import org.springframework.boot.actuate.cache.CacheStatisticsProvider; import org.springframework.boot.actuate.cache.CacheStatisticsProvider;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
@ -52,6 +45,14 @@ import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import com.google.common.cache.CacheBuilder;
import com.hazelcast.cache.HazelcastCachingProvider;
import com.hazelcast.config.Config;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.spring.cache.HazelcastCacheManager;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;

@ -51,8 +51,8 @@ abstract class CacheConfigFileCondition extends SpringBootCondition {
RelaxedPropertyResolver resolver = new RelaxedPropertyResolver( RelaxedPropertyResolver resolver = new RelaxedPropertyResolver(
context.getEnvironment(), this.configPrefix); context.getEnvironment(), this.configPrefix);
if (resolver.containsProperty("config")) { if (resolver.containsProperty("config")) {
return ConditionOutcome.match("A '" + this.configPrefix + ".config' " + return ConditionOutcome.match("A '" + this.configPrefix + ".config' "
"property is specified"); + "property is specified");
} }
return getResourceOutcome(context, metadata); return getResourceOutcome(context, metadata);
} }

@ -92,14 +92,15 @@ public class CacheProperties {
/** /**
* Resolve the config location if set. * Resolve the config location if set.
* @param config the config resource
* @return the location or {@code null} if it is not set * @return the location or {@code null} if it is not set
* @throws IllegalArgumentException if the config attribute is set to a unknown * @throws IllegalArgumentException if the config attribute is set to a unknown
* location * location
*/ */
public Resource resolveConfigLocation(Resource config) { public Resource resolveConfigLocation(Resource config) {
if (config != null) { if (config != null) {
Assert.isTrue(config.exists(), "Cache configuration does not " + Assert.isTrue(config.exists(), "Cache configuration does not " + "exist '"
"exist '" + config.getDescription() + "'"); + config.getDescription() + "'");
return config; return config;
} }
return null; return null;
@ -116,12 +117,13 @@ public class CacheProperties {
private Resource config; private Resource config;
public Resource getConfig() { public Resource getConfig() {
return config; return this.config;
} }
public void setConfig(Resource config) { public void setConfig(Resource config) {
this.config = config; this.config = config;
} }
} }
/** /**
@ -135,7 +137,7 @@ public class CacheProperties {
private Resource config; private Resource config;
public Resource getConfig() { public Resource getConfig() {
return config; return this.config;
} }
public void setConfig(Resource config) { public void setConfig(Resource config) {
@ -155,7 +157,7 @@ public class CacheProperties {
private Resource config; private Resource config;
public Resource getConfig() { public Resource getConfig() {
return config; return this.config;
} }
public void setConfig(Resource config) { public void setConfig(Resource config) {
@ -170,8 +172,8 @@ public class CacheProperties {
public static class JCache { public static class JCache {
/** /**
* The location of the configuration file to use to initialize the cache manager. The * The location of the configuration file to use to initialize the cache manager.
* configuration file is dependent of the underlying cache implementation. * The configuration file is dependent of the underlying cache implementation.
*/ */
private Resource config; private Resource config;
@ -191,12 +193,13 @@ public class CacheProperties {
} }
public Resource getConfig() { public Resource getConfig() {
return config; return this.config;
} }
public void setConfig(Resource config) { public void setConfig(Resource config) {
this.config = config; this.config = config;
} }
} }
/** /**

@ -55,8 +55,8 @@ class EhCacheCacheConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public CacheManager ehCacheCacheManager() { public CacheManager ehCacheCacheManager() {
Resource location = this.cacheProperties.resolveConfigLocation( Resource location = this.cacheProperties
this.cacheProperties.getEhcache().getConfig()); .resolveConfigLocation(this.cacheProperties.getEhcache().getConfig());
if (location != null) { if (location != null) {
return EhCacheManagerUtils.buildCacheManager(location); return EhCacheManagerUtils.buildCacheManager(location);
} }

@ -64,8 +64,8 @@ class HazelcastCacheConfiguration {
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public HazelcastInstance hazelcastInstance() throws IOException { public HazelcastInstance hazelcastInstance() throws IOException {
Resource location = this.cacheProperties.resolveConfigLocation( Resource location = this.cacheProperties
this.cacheProperties.getHazelcast().getConfig()); .resolveConfigLocation(this.cacheProperties.getHazelcast().getConfig());
if (location != null) { if (location != null) {
Config cfg = new XmlConfigBuilder(location.getURL()).build(); Config cfg = new XmlConfigBuilder(location.getURL()).build();
return Hazelcast.newHazelcastInstance(cfg); return Hazelcast.newHazelcastInstance(cfg);
@ -81,8 +81,8 @@ class HazelcastCacheConfiguration {
static class ConfigAvailableCondition extends CacheConfigFileCondition { static class ConfigAvailableCondition extends CacheConfigFileCondition {
public ConfigAvailableCondition() { public ConfigAvailableCondition() {
super("Hazelcast", "spring.config.hazelcast", super("Hazelcast", "spring.config.hazelcast", "file:./hazelcast.xml",
"file:./hazelcast.xml", "classpath:/hazelcast.xml"); "classpath:/hazelcast.xml");
} }
@Override @Override

@ -24,7 +24,6 @@ import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager; import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager; import org.infinispan.manager.EmbeddedCacheManager;
import org.infinispan.spring.provider.SpringEmbeddedCacheManager; import org.infinispan.spring.provider.SpringEmbeddedCacheManager;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@ -62,19 +61,20 @@ public class InfinispanCacheConfiguration {
@Bean(destroyMethod = "stop") @Bean(destroyMethod = "stop")
@ConditionalOnMissingBean @ConditionalOnMissingBean
public EmbeddedCacheManager infinispanCacheManager() throws IOException { public EmbeddedCacheManager infinispanCacheManager() throws IOException {
EmbeddedCacheManager infinispanCacheManager = createEmbeddedCacheManager(); EmbeddedCacheManager cacheManager = createEmbeddedCacheManager();
List<String> cacheNames = this.cacheProperties.getCacheNames(); List<String> cacheNames = this.cacheProperties.getCacheNames();
if (!CollectionUtils.isEmpty(cacheNames)) { if (!CollectionUtils.isEmpty(cacheNames)) {
for (String cacheName : cacheNames) { for (String cacheName : cacheNames) {
infinispanCacheManager.defineConfiguration(cacheName, getDefaultCacheConfiguration()); cacheManager.defineConfiguration(cacheName,
getDefaultCacheConfiguration());
} }
} }
return infinispanCacheManager; return cacheManager;
} }
private EmbeddedCacheManager createEmbeddedCacheManager() throws IOException { private EmbeddedCacheManager createEmbeddedCacheManager() throws IOException {
Resource location = this.cacheProperties.resolveConfigLocation( Resource location = this.cacheProperties
this.cacheProperties.getInfinispan().getConfig()); .resolveConfigLocation(this.cacheProperties.getInfinispan().getConfig());
if (location != null) { if (location != null) {
InputStream in = location.getInputStream(); InputStream in = location.getInputStream();
try { try {
@ -89,7 +89,7 @@ public class InfinispanCacheConfiguration {
private org.infinispan.configuration.cache.Configuration getDefaultCacheConfiguration() { private org.infinispan.configuration.cache.Configuration getDefaultCacheConfiguration() {
if (this.defaultConfigurationBuilder != null) { if (this.defaultConfigurationBuilder != null) {
return defaultConfigurationBuilder.build(); return this.defaultConfigurationBuilder.build();
} }
return new ConfigurationBuilder().build(); return new ConfigurationBuilder().build();
} }

@ -91,8 +91,8 @@ class JCacheCacheConfiguration {
private CacheManager createCacheManager() throws IOException { private CacheManager createCacheManager() throws IOException {
CachingProvider cachingProvider = getCachingProvider(this.cacheProperties CachingProvider cachingProvider = getCachingProvider(this.cacheProperties
.getJcache().getProvider()); .getJcache().getProvider());
Resource configLocation = this.cacheProperties.resolveConfigLocation( Resource configLocation = this.cacheProperties
this.cacheProperties.getJcache().getConfig()); .resolveConfigLocation(this.cacheProperties.getJcache().getConfig());
if (configLocation != null) { if (configLocation != null) {
return cachingProvider.getCacheManager(configLocation.getURI(), return cachingProvider.getCacheManager(configLocation.getURI(),
cachingProvider.getDefaultClassLoader(), cachingProvider.getDefaultClassLoader(),
@ -135,8 +135,8 @@ class JCacheCacheConfiguration {
/** /**
* Determine if JCache is available. This either kicks in if a provider is available * Determine if JCache is available. This either kicks in if a provider is available
* as defined per {@link JCacheProviderAvailableCondition} or if a {@link CacheManager} * as defined per {@link JCacheProviderAvailableCondition} or if a
* has already been defined. * {@link CacheManager} has already been defined.
*/ */
@Order(Ordered.LOWEST_PRECEDENCE) @Order(Ordered.LOWEST_PRECEDENCE)
static class JCacheAvailableCondition extends AnyNestedCondition { static class JCacheAvailableCondition extends AnyNestedCondition {
@ -146,10 +146,12 @@ class JCacheCacheConfiguration {
} }
@Conditional(JCacheProviderAvailableCondition.class) @Conditional(JCacheProviderAvailableCondition.class)
static class JCacheProvider {} static class JCacheProvider {
}
@ConditionalOnSingleCandidate(CacheManager.class) @ConditionalOnSingleCandidate(CacheManager.class)
static class CustomJCacheCacheManager {} static class CustomJCacheCacheManager {
}
} }

@ -19,16 +19,14 @@ package org.springframework.boot.autoconfigure.cache;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import javax.cache.configuration.CompleteConfiguration; import javax.cache.configuration.CompleteConfiguration;
import javax.cache.configuration.MutableConfiguration; import javax.cache.configuration.MutableConfiguration;
import javax.cache.expiry.CreatedExpiryPolicy; import javax.cache.expiry.CreatedExpiryPolicy;
import javax.cache.expiry.Duration; import javax.cache.expiry.Duration;
import com.google.common.cache.CacheBuilder;
import com.hazelcast.cache.HazelcastCachingProvider;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.spring.cache.HazelcastCacheManager;
import net.sf.ehcache.Status; import net.sf.ehcache.Status;
import org.infinispan.configuration.cache.ConfigurationBuilder; import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.jcache.embedded.JCachingProvider; import org.infinispan.jcache.embedded.JCachingProvider;
import org.infinispan.spring.provider.SpringEmbeddedCacheManager; import org.infinispan.spring.provider.SpringEmbeddedCacheManager;
@ -36,7 +34,6 @@ import org.junit.After;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.ExpectedException; import org.junit.rules.ExpectedException;
import org.springframework.beans.DirectFieldAccessor; import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
@ -65,6 +62,11 @@ import org.springframework.core.io.Resource;
import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import com.google.common.cache.CacheBuilder;
import com.hazelcast.cache.HazelcastCachingProvider;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.spring.cache.HazelcastCacheManager;
import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.contains;
@ -257,7 +259,8 @@ public class CacheAutoConfigurationTests {
public void jCacheCacheWithExistingJCacheManager() { public void jCacheCacheWithExistingJCacheManager() {
load(JCacheCustomCacheManager.class, "spring.cache.type=jcache"); load(JCacheCustomCacheManager.class, "spring.cache.type=jcache");
JCacheCacheManager cacheManager = validateCacheManager(JCacheCacheManager.class); JCacheCacheManager cacheManager = validateCacheManager(JCacheCacheManager.class);
assertThat(cacheManager.getCacheManager(), is(this.context.getBean("customJCacheCacheManager"))); assertThat(cacheManager.getCacheManager(),
is(this.context.getBean("customJCacheCacheManager")));
} }
@Test @Test
@ -318,7 +321,8 @@ public class CacheAutoConfigurationTests {
public void ehCacheCacheWithExistingCacheManager() { public void ehCacheCacheWithExistingCacheManager() {
load(EhCacheCustomCacheManager.class, "spring.cache.type=ehcache"); load(EhCacheCustomCacheManager.class, "spring.cache.type=ehcache");
EhCacheCacheManager cacheManager = validateCacheManager(EhCacheCacheManager.class); EhCacheCacheManager cacheManager = validateCacheManager(EhCacheCacheManager.class);
assertThat(cacheManager.getCacheManager(), is(this.context.getBean("customEhCacheCacheManager"))); assertThat(cacheManager.getCacheManager(),
is(this.context.getBean("customEhCacheCacheManager")));
} }
@Test @Test
@ -330,12 +334,14 @@ public class CacheAutoConfigurationTests {
assertThat(cacheManager.getCacheNames(), containsInAnyOrder("defaultCache")); assertThat(cacheManager.getCacheNames(), containsInAnyOrder("defaultCache"));
assertThat(cacheManager.getCacheNames(), hasSize(1)); assertThat(cacheManager.getCacheNames(), hasSize(1));
assertThat(this.context.getBean(HazelcastInstance.class), assertThat(this.context.getBean(HazelcastInstance.class),
is(new DirectFieldAccessor(cacheManager).getPropertyValue("hazelcastInstance"))); is(new DirectFieldAccessor(cacheManager)
.getPropertyValue("hazelcastInstance")));
} }
@Test @Test
public void hazelcastCacheWithConfig() { public void hazelcastCacheWithConfig() {
load(DefaultCacheConfiguration.class, "spring.cache.type=hazelcast", load(DefaultCacheConfiguration.class,
"spring.cache.type=hazelcast",
"spring.cache.hazelcast.config=org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml"); "spring.cache.hazelcast.config=org/springframework/boot/autoconfigure/cache/hazelcast-specific.xml");
HazelcastCacheManager cacheManager = validateCacheManager(HazelcastCacheManager.class); HazelcastCacheManager cacheManager = validateCacheManager(HazelcastCacheManager.class);
cacheManager.getCache("foobar"); cacheManager.getCache("foobar");
@ -355,7 +361,9 @@ public class CacheAutoConfigurationTests {
public void hazelcastCacheWithExistingHazelcastInstance() { public void hazelcastCacheWithExistingHazelcastInstance() {
load(HazelcastCustomHazelcastInstance.class, "spring.cache.type=hazelcast"); load(HazelcastCustomHazelcastInstance.class, "spring.cache.type=hazelcast");
HazelcastCacheManager cacheManager = validateCacheManager(HazelcastCacheManager.class); HazelcastCacheManager cacheManager = validateCacheManager(HazelcastCacheManager.class);
assertThat(new DirectFieldAccessor(cacheManager).getPropertyValue("hazelcastInstance"), assertThat(
new DirectFieldAccessor(cacheManager)
.getPropertyValue("hazelcastInstance"),
is(this.context.getBean("customHazelcastInstance"))); is(this.context.getBean("customHazelcastInstance")));
} }
@ -380,8 +388,7 @@ public class CacheAutoConfigurationTests {
JCacheCacheManager cacheManager = validateCacheManager(JCacheCacheManager.class); JCacheCacheManager cacheManager = validateCacheManager(JCacheCacheManager.class);
Resource configResource = new ClassPathResource(configLocation); Resource configResource = new ClassPathResource(configLocation);
assertThat(cacheManager.getCacheManager().getURI(), assertThat(cacheManager.getCacheManager().getURI(), is(configResource.getURI()));
is(configResource.getURI()));
} }
@Test @Test
@ -435,8 +442,7 @@ public class CacheAutoConfigurationTests {
JCacheCacheManager cacheManager = validateCacheManager(JCacheCacheManager.class); JCacheCacheManager cacheManager = validateCacheManager(JCacheCacheManager.class);
Resource configResource = new ClassPathResource(configLocation); Resource configResource = new ClassPathResource(configLocation);
assertThat(cacheManager.getCacheManager().getURI(), assertThat(cacheManager.getCacheManager().getURI(), is(configResource.getURI()));
is(configResource.getURI()));
} }
@Test @Test
@ -562,7 +568,8 @@ public class CacheAutoConfigurationTests {
@Bean @Bean
public javax.cache.CacheManager customJCacheCacheManager() { public javax.cache.CacheManager customJCacheCacheManager() {
javax.cache.CacheManager cacheManager = mock(javax.cache.CacheManager.class); javax.cache.CacheManager cacheManager = mock(javax.cache.CacheManager.class);
when(cacheManager.getCacheNames()).thenReturn(Collections.<String>emptyList()); when(cacheManager.getCacheNames()).thenReturn(
Collections.<String> emptyList());
return cacheManager; return cacheManager;
} }

@ -16,8 +16,9 @@ the application starts a client invokes the service with a random code every 500
can look at the `/metrics` endpoint to review the cache statistics if your chosen can look at the `/metrics` endpoint to review the cache statistics if your chosen
caching provider is supported. caching provider is supported.
== Using the JSR-107 annotations
== Using the JSR-107 annotations
The sample uses Spring's cache annotation. If you want to use the JSR-107 annotations The sample uses Spring's cache annotation. If you want to use the JSR-107 annotations
instead, simply add the `javax.cache:cache-api` dependency to the project. No further instead, simply add the `javax.cache:cache-api` dependency to the project. No further
configuration is necessary. configuration is necessary.
@ -25,35 +26,40 @@ configuration is necessary.
NOTE: You can use the JSR-107 annotations with _any_ cache provider; a JSR-107 compliant NOTE: You can use the JSR-107 annotations with _any_ cache provider; a JSR-107 compliant
cache provider is not necessary. cache provider is not necessary.
== Using a different cache provider
== Using a different cache provider
Initially, the project does not define any caching library so the abstraction works Initially, the project does not define any caching library so the abstraction works
on simple `ConcurrentHashMap`-based caches. You can try out your favorite caching library on simple `ConcurrentHashMap`-based caches. You can try out your favorite caching library
as explained below. as explained below.
=== EhCache 2.x
=== EhCache 2.x
Simply add the `net.sf.ehcache:ehcache` dependency to the project. Since there is a Simply add the `net.sf.ehcache:ehcache` dependency to the project. Since there is a
default `ehcache.xml` configuration file at the root of the classpath, it is automatically default `ehcache.xml` configuration file at the root of the classpath, it is automatically
used to configure the underlying `CacheManager`. used to configure the underlying `CacheManager`.
=== Hazelcast
=== Hazelcast
Both `com.hazelcast:hazelcast` and `com.hazelcast:hazelcast-spring` should be added to Both `com.hazelcast:hazelcast` and `com.hazelcast:hazelcast-spring` should be added to
the project to enable support for Hazelcast. Since there is a default `hazelcast.xml` the project to enable support for Hazelcast. Since there is a default `hazelcast.xml`
configuration file at the root of the classpath, it is used to automatically configure configuration file at the root of the classpath, it is used to automatically configure
the underlying `HazelcastInstance`. the underlying `HazelcastInstance`.
=== Infinispan
=== Infinispan
Simply add the `org.infinispan:infinispan-spring4` dependency to enable support for Simply add the `org.infinispan:infinispan-spring4` dependency to enable support for
Infinispan. There is no default location that Infinispan uses to look for a config Infinispan. There is no default location that Infinispan uses to look for a config
file so if you don't specify anything it will bootstrap on a hardcoded default. You file so if you don't specify anything it will bootstrap on a hardcoded default. You
can set the `spring.cache.infinispan.config` property to use the provided can set the `spring.cache.infinispan.config` property to use the provided
`infinispan.xml` configuration instead. `infinispan.xml` configuration instead.
=== JCache (JSR-107)
=== JCache (JSR-107)
If you want to configure your cache infrastructure via the standard, you need a compliant If you want to configure your cache infrastructure via the standard, you need a compliant
implementation. You could try the following: implementation. You could try the following:
@ -65,13 +71,15 @@ Since Spring Boot supports the native cache library and the JCache wrapper, you
should set the `spring.cache.type` property to `jcache` to specify that you want the should set the `spring.cache.type` property to `jcache` to specify that you want the
cache manager to be auto-configured that way. cache manager to be auto-configured that way.
=== Redis
=== Redis
Add the `spring-boot-starter-redis` and make sure it is configured properly (by default, Add the `spring-boot-starter-redis` and make sure it is configured properly (by default,
a redis instance with the default settings is expected on your local box). a redis instance with the default settings is expected on your local box).
=== Guava
=== Guava
Spring Boot does not provide any dependency management for _Guava_ so you'll have to add Spring Boot does not provide any dependency management for _Guava_ so you'll have to add
the `com.google.guava:guava` dependency with a version. You can customize how caches are the `com.google.guava:guava` dependency with a version. You can customize how caches are
created in different ways, see `application.properties` for an example and the created in different ways, see `application.properties` for an example and the

@ -24,7 +24,6 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId> <artifactId>spring-boot-starter-cache</artifactId>
</dependency> </dependency>
<!-- Only used to expose cache metrics --> <!-- Only used to expose cache metrics -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -34,12 +33,14 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId> <artifactId>spring-boot-starter-actuator</artifactId>
</dependency> </dependency>
<!-- Additional cache providers (uncomment to try them) -->
<!-- Additional cache providers <!--
<dependency> <dependency>
<groupId>net.sf.ehcache</groupId> <groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId> <artifactId>ehcache</artifactId>
</dependency> </dependency>
-->
<!--
<dependency> <dependency>
<groupId>com.hazelcast</groupId> <groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId> <artifactId>hazelcast</artifactId>
@ -48,6 +49,8 @@
<groupId>com.hazelcast</groupId> <groupId>com.hazelcast</groupId>
<artifactId>hazelcast-spring</artifactId> <artifactId>hazelcast-spring</artifactId>
</dependency> </dependency>
-->
<!--
<dependency> <dependency>
<groupId>org.infinispan</groupId> <groupId>org.infinispan</groupId>
<artifactId>infinispan-spring4</artifactId> <artifactId>infinispan-spring4</artifactId>
@ -56,17 +59,20 @@
<groupId>org.infinispan</groupId> <groupId>org.infinispan</groupId>
<artifactId>infinispan-jcache</artifactId> <artifactId>infinispan-jcache</artifactId>
</dependency> </dependency>
-->
<!--
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId> <artifactId>spring-boot-starter-redis</artifactId>
</dependency> </dependency>
-->
<!--
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>
<version>18.0</version> <version>18.0</version>
</dependency> </dependency>
--> -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId> <artifactId>spring-boot-starter-test</artifactId>

@ -0,0 +1,42 @@
/*
* Copyright 2012-2015 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;
@Component
public class CacheManagerCheck implements CommandLineRunner {
private final CacheManager cacheManager;
@Autowired
public CacheManagerCheck(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public void run(String... strings) throws Exception {
SampleCacheApplication.logger.info("\n\n"
+ "=========================================================\n"
+ "Using cache manager: " + this.cacheManager.getClass().getName() + "\n"
+ "=========================================================\n\n");
}
}

@ -28,22 +28,26 @@ public class Country implements Serializable {
} }
public String getCode() { public String getCode() {
return code; return this.code;
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) {
if (o == null || getClass() != o.getClass()) return false; return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Country country = (Country) o; Country country = (Country) o;
return code.equals(country.code); return this.code.equals(country.code);
} }
@Override @Override
public int hashCode() { public int hashCode() {
return code.hashCode(); return this.code.hashCode();
} }
} }

@ -18,46 +18,21 @@ package sample;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
@EnableCaching @EnableCaching
@EnableScheduling @EnableScheduling
@SpringBootApplication @SpringBootApplication
public class SampleCacheApplication { public class SampleCacheApplication {
private static final Logger logger = LoggerFactory.getLogger(SampleCacheApplication.class); static final Logger logger = LoggerFactory.getLogger(SampleCacheApplication.class);
public static void main(String[] args) { public static void main(String[] args) {
new SpringApplicationBuilder() new SpringApplicationBuilder().sources(SampleCacheApplication.class)
.sources(SampleCacheApplication.class) .profiles("app").run(args);
.profiles("app")
.run(args);
}
@Component
static class CacheManagerCheck implements CommandLineRunner {
private final CacheManager cacheManager;
@Autowired
CacheManagerCheck(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}
@Override
public void run(String... strings) throws Exception {
logger.info("\n\n" + "=========================================================\n"
+ "Using cache manager: " + this.cacheManager.getClass().getName() + "\n"
+ "=========================================================\n\n");
}
} }
} }

@ -29,23 +29,26 @@ import org.springframework.stereotype.Component;
@Profile("app") @Profile("app")
class SampleClient { class SampleClient {
private static final List<String> SAMPLE_COUNTRY_CODES = Arrays.asList("AF", "AX", "AL", "DZ", "AS", private static final List<String> SAMPLE_COUNTRY_CODES = Arrays.asList("AF", "AX",
"AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT", "AZ", "BS", "BH", "BD", "BB", "BY", "AL", "DZ", "AS", "AD", "AO", "AI", "AQ", "AG", "AR", "AM", "AW", "AU", "AT",
"BE", "BZ", "BJ", "BM", "BT", "BO", "BQ", "BA", "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI", "AZ", "BS", "BH", "BD", "BB", "BY", "BE", "BZ", "BJ", "BM", "BT", "BO", "BQ",
"KH", "CM", "CA", "CV", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK", "BA", "BW", "BV", "BR", "IO", "BN", "BG", "BF", "BI", "KH", "CM", "CA", "CV",
"CR", "CI", "HR", "CU", "CW", "CY", "CZ", "DK", "DJ", "DM", "DO", "EC", "EG", "SV", "GQ", "ER", "KY", "CF", "TD", "CL", "CN", "CX", "CC", "CO", "KM", "CG", "CD", "CK", "CR",
"EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA", "GM", "GE", "DE", "GH", "GI", "CI", "HR", "CU", "CW", "CY", "CZ", "DK", "DJ", "DM", "DO", "EC", "EG", "SV",
"GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN", "GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU", "GQ", "ER", "EE", "ET", "FK", "FO", "FJ", "FI", "FR", "GF", "PF", "TF", "GA",
"IS", "IN", "ID", "IR", "IQ", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "GM", "GE", "DE", "GH", "GI", "GR", "GL", "GD", "GP", "GU", "GT", "GG", "GN",
"KP", "KR", "KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK", "MG", "GW", "GY", "HT", "HM", "VA", "HN", "HK", "HU", "IS", "IN", "ID", "IR", "IQ",
"MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM", "MD", "MC", "MN", "ME", "IE", "IM", "IL", "IT", "JM", "JP", "JE", "JO", "KZ", "KE", "KI", "KP", "KR",
"MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC", "NZ", "NI", "NE", "NG", "NU", "NF", "MP", "KW", "KG", "LA", "LV", "LB", "LS", "LR", "LY", "LI", "LT", "LU", "MO", "MK",
"NO", "OM", "PK", "PW", "PS", "PA", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "RE", "MG", "MW", "MY", "MV", "ML", "MT", "MH", "MQ", "MR", "MU", "YT", "MX", "FM",
"RO", "RU", "RW", "BL", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS", "MD", "MC", "MN", "ME", "MS", "MA", "MZ", "MM", "NA", "NR", "NP", "NL", "NC",
"SC", "SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES", "LK", "SD", "SR", "SJ", "NZ", "NI", "NE", "NG", "NU", "NF", "MP", "NO", "OM", "PK", "PW", "PS", "PA",
"SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG", "TK", "TO", "TT", "TN", "TR", "TM", "PG", "PY", "PE", "PH", "PN", "PL", "PT", "PR", "QA", "RE", "RO", "RU", "RW",
"TC", "TV", "UG", "UA", "AE", "GB", "US", "UM", "UY", "UZ", "VU", "VE", "VN", "VG", "VI", "WF", "BL", "SH", "KN", "LC", "MF", "PM", "VC", "WS", "SM", "ST", "SA", "SN", "RS",
"EH", "YE", "ZM", "ZW"); "SC", "SL", "SG", "SX", "SK", "SI", "SB", "SO", "ZA", "GS", "SS", "ES", "LK",
"SD", "SR", "SJ", "SZ", "SE", "CH", "SY", "TW", "TJ", "TZ", "TH", "TL", "TG",
"TK", "TO", "TT", "TN", "TR", "TM", "TC", "TV", "UG", "UA", "AE", "GB", "US",
"UM", "UY", "UZ", "VU", "VE", "VN", "VG", "VI", "WF", "EH", "YE", "ZM", "ZW");
private final CountryRepository countryService; private final CountryRepository countryService;
@ -59,7 +62,8 @@ class SampleClient {
@Scheduled(fixedDelay = 500) @Scheduled(fixedDelay = 500)
public void retrieveCountry() { public void retrieveCountry() {
String randomCode = SAMPLE_COUNTRY_CODES.get(random.nextInt(SAMPLE_COUNTRY_CODES.size())); String randomCode = SAMPLE_COUNTRY_CODES.get(this.random
.nextInt(SAMPLE_COUNTRY_CODES.size()));
System.out.println("Looking for country with code '" + randomCode + "'"); System.out.println("Looking for country with code '" + randomCode + "'");
this.countryService.findByCode(randomCode); this.countryService.findByCode(randomCode);
} }

@ -1,5 +1,3 @@
# #
# Infinispan configuration file location. # Infinispan configuration file location.
# #

@ -18,7 +18,6 @@ package sample;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.cache.Cache; import org.springframework.cache.Cache;
@ -34,7 +33,6 @@ import static org.hamcrest.core.IsNull.notNullValue;
@SpringApplicationConfiguration(classes = { SampleCacheApplication.class }) @SpringApplicationConfiguration(classes = { SampleCacheApplication.class })
public class SampleCacheApplicationTests { public class SampleCacheApplicationTests {
@Autowired @Autowired
private CacheManager cacheManager; private CacheManager cacheManager;

Loading…
Cancel
Save