Add custom cache manager per cache operation
It is now possible to specify the CacheManager to use per operation. The related cache annotation now has an extra attribute that defines the name of the CacheManager bean to use. The cache manager that was previously used is therefore a 'default' cache manager (i.e. the one to use if no custom cache manager has been set on the operation). Issue: SPR-8696
This commit is contained in:
@@ -34,6 +34,7 @@ import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* @author Costin Leau
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class AnnotationCacheOperationSourceTests {
|
||||
|
||||
@@ -116,6 +117,22 @@ public class AnnotationCacheOperationSourceTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomCacheManager() {
|
||||
Collection<CacheOperation> ops = getOps("customCacheManager");
|
||||
assertEquals(1, ops.size());
|
||||
CacheOperation cacheOperation = ops.iterator().next();
|
||||
assertEquals("Custom cache manager not set", "custom", cacheOperation.getCacheManager());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomCacheManagerInherited() {
|
||||
Collection<CacheOperation> ops = getOps("customCacheManagerInherited");
|
||||
assertEquals(1, ops.size());
|
||||
CacheOperation cacheOperation = ops.iterator().next();
|
||||
assertEquals("Custom cache manager not set", "custom", cacheOperation.getCacheManager());
|
||||
}
|
||||
|
||||
private static class AnnotatedClass {
|
||||
@Cacheable("test")
|
||||
public void singular() {
|
||||
@@ -134,6 +151,10 @@ public class AnnotationCacheOperationSourceTests {
|
||||
public void customKeyGenerator() {
|
||||
}
|
||||
|
||||
@Cacheable(value = "test", cacheManager = "custom")
|
||||
public void customCacheManager() {
|
||||
}
|
||||
|
||||
@EvictFoo
|
||||
public void singleStereotype() {
|
||||
}
|
||||
@@ -155,6 +176,10 @@ public class AnnotationCacheOperationSourceTests {
|
||||
@Cacheable(value = "test", key = "#root.methodName", keyGenerator = "custom")
|
||||
public void invalidKeyAndKeyGeneratorSet() {
|
||||
}
|
||||
|
||||
@CacheableFooCustomCacheManager
|
||||
public void customCacheManagerInherited() {
|
||||
}
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@@ -169,6 +194,13 @@ public class AnnotationCacheOperationSourceTests {
|
||||
public @interface CacheableFooCustomKeyGenerator {
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Cacheable(value = "foo", cacheManager = "custom")
|
||||
public @interface CacheableFooCustomCacheManager {
|
||||
|
||||
}
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@CacheEvict(value = "foo")
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.context.ApplicationContext;
|
||||
* @author Costin Leau
|
||||
* @author Chris Beams
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public abstract class AbstractAnnotationTests {
|
||||
|
||||
@@ -47,6 +48,8 @@ public abstract class AbstractAnnotationTests {
|
||||
|
||||
protected CacheManager cm;
|
||||
|
||||
protected CacheManager customCm;
|
||||
|
||||
/** @return a refreshed application context */
|
||||
protected abstract ApplicationContext getApplicationContext();
|
||||
|
||||
@@ -55,7 +58,9 @@ public abstract class AbstractAnnotationTests {
|
||||
ctx = getApplicationContext();
|
||||
cs = ctx.getBean("service", CacheableService.class);
|
||||
ccs = ctx.getBean("classService", CacheableService.class);
|
||||
cm = ctx.getBean(CacheManager.class);
|
||||
cm = ctx.getBean("cacheManager", CacheManager.class);
|
||||
customCm = ctx.getBean("customCacheManager", CacheManager.class);
|
||||
|
||||
Collection<String> cn = cm.getCacheNames();
|
||||
assertTrue(cn.contains("default"));
|
||||
assertTrue(cn.contains("secondary"));
|
||||
@@ -591,6 +596,26 @@ public abstract class AbstractAnnotationTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomCacheManager() {
|
||||
Object key = new Object();
|
||||
Object r1 = cs.customCacheManager(key);
|
||||
assertSame(r1, cs.customCacheManager(key));
|
||||
Cache cache = customCm.getCache("default");
|
||||
assertNotNull(cache.get(key));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnknownCustomCacheManager() {
|
||||
try {
|
||||
Object param = new Object();
|
||||
cs.unknownCustomCacheManager(param);
|
||||
fail("should have failed with NoSuchBeanDefinitionException");
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullArg() throws Exception {
|
||||
testNullArg(cs);
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.springframework.cache.annotation.Caching;
|
||||
/**
|
||||
* @author Costin Leau
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
@Cacheable("default")
|
||||
public class AnnotatedClassCacheableService implements CacheableService<Object> {
|
||||
@@ -119,6 +120,18 @@ public class AnnotatedClassCacheableService implements CacheableService<Object>
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "default", cacheManager = "customCacheManager")
|
||||
public Object customCacheManager(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "default", cacheManager = "unknownBeanName")
|
||||
public Object unknownCustomCacheManager(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CachePut("default")
|
||||
public Object update(Object arg1) {
|
||||
|
||||
@@ -21,6 +21,7 @@ package org.springframework.cache.config;
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public interface CacheableService<T> {
|
||||
|
||||
@@ -62,6 +63,10 @@ public interface CacheableService<T> {
|
||||
|
||||
T unknownCustomKeyGenerator(Object arg1);
|
||||
|
||||
T customCacheManager(Object arg1);
|
||||
|
||||
T unknownCustomCacheManager(Object arg1);
|
||||
|
||||
T throwChecked(Object arg1) throws Exception;
|
||||
|
||||
T throwUnchecked(Object arg1);
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.cache.annotation.Caching;
|
||||
*
|
||||
* @author Costin Leau
|
||||
* @author Phillip Webb
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class DefaultCacheableService implements CacheableService<Long> {
|
||||
|
||||
@@ -121,6 +122,18 @@ public class DefaultCacheableService implements CacheableService<Long> {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "default", cacheManager = "customCacheManager")
|
||||
public Long customCacheManager(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Cacheable(value = "default", cacheManager = "unknownBeanName")
|
||||
public Long unknownCustomCacheManager(Object arg1) {
|
||||
return counter.getAndIncrement();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CachePut("default")
|
||||
public Long update(Object arg1) {
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
* Integration tests for @EnableCaching and its related @Configuration classes.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class EnableCachingTests extends AbstractAnnotationTests {
|
||||
|
||||
@@ -145,6 +146,13 @@ public class EnableCachingTests extends AbstractAnnotationTests {
|
||||
public KeyGenerator customKeyGenerator() {
|
||||
return new SomeCustomKeyGenerator();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CacheManager customCacheManager() {
|
||||
SimpleCacheManager cm = new SimpleCacheManager();
|
||||
cm.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
|
||||
return cm;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user