Skip to content

Commit

Permalink
Add custom cache manager per cache operation
Browse files Browse the repository at this point in the history
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
  • Loading branch information
snicoll committed Mar 31, 2014
1 parent 81c2080 commit f06cad9
Show file tree
Hide file tree
Showing 21 changed files with 243 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,18 @@ public Object unknownCustomKeyGenerator(Object arg1) {
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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ public Long unknownCustomKeyGenerator(Object arg1) {
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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">


<!--
Expand Down Expand Up @@ -45,6 +42,16 @@

<bean id="customKeyGenerator" class="org.springframework.cache.config.SomeCustomKeyGenerator" />

<bean id="customCacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
<property name="name" value="default"/>
</bean>
</set>
</property>
</bean>

<bean id="debugInterceptor" class="org.springframework.aop.interceptor.DebugInterceptor"/>

<bean id="service" class="org.springframework.cache.config.DefaultCacheableService"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
* a cache invalidate operation.
*
* @author Costin Leau
* @author Stephane Nicoll
* @since 3.1
*/
@Target({ElementType.METHOD, ElementType.TYPE})
Expand Down Expand Up @@ -56,6 +57,11 @@
*/
String keyGenerator() default "";

/**
* The bean name of the custom {@link org.springframework.cache.CacheManager} to use.
*/
String cacheManager() default "";

/**
* Spring Expression Language (SpEL) attribute used for conditioning the method caching.
* <p>Default is "", meaning the method is always cached.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
*
* @author Costin Leau
* @author Phillip Webb
* @author Stephane Nicoll
* @since 3.1
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
Expand Down Expand Up @@ -61,6 +62,11 @@
*/
String keyGenerator() default "";

/**
* The bean name of the custom {@link org.springframework.cache.CacheManager} to use.
*/
String cacheManager() default "";

/**
* Spring Expression Language (SpEL) attribute used for conditioning the cache update.
* <p>Default is "", meaning the method result is always cached.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
*
* @author Costin Leau
* @author Phillip Webb
* @author Stephane Nicoll
* @since 3.1
*/
@Target({ElementType.METHOD, ElementType.TYPE})
Expand Down Expand Up @@ -59,6 +60,11 @@
*/
String keyGenerator() default "";

/**
* The bean name of the custom {@link org.springframework.cache.CacheManager} to use.
*/
String cacheManager() default "";

/**
* Spring Expression Language (SpEL) attribute used for conditioning the method caching.
* <p>Default is "", meaning the method is always cached.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
* @author Juergen Hoeller
* @author Chris Beams
* @author Phillip Webb
* @author Stephane Nicoll
* @since 3.1
*/
@SuppressWarnings("serial")
Expand Down Expand Up @@ -88,6 +89,7 @@ CacheableOperation parseCacheableAnnotation(AnnotatedElement ae, Cacheable cachi
cuo.setUnless(caching.unless());
cuo.setKey(caching.key());
cuo.setKeyGenerator(caching.keyGenerator());
cuo.setCacheManager(caching.cacheManager());
cuo.setName(ae.toString());

checkKeySourceConsistency(ae, caching.key(), caching.keyGenerator());
Expand All @@ -100,6 +102,7 @@ CacheEvictOperation parseEvictAnnotation(AnnotatedElement ae, CacheEvict caching
ceo.setCondition(caching.condition());
ceo.setKey(caching.key());
ceo.setKeyGenerator(caching.keyGenerator());
ceo.setCacheManager(caching.cacheManager());
ceo.setCacheWide(caching.allEntries());
ceo.setBeforeInvocation(caching.beforeInvocation());
ceo.setName(ae.toString());
Expand All @@ -115,6 +118,7 @@ CacheOperation parseUpdateAnnotation(AnnotatedElement ae, CachePut caching) {
cuo.setUnless(caching.unless());
cuo.setKey(caching.key());
cuo.setKeyGenerator(caching.keyGenerator());
cuo.setCacheManager(caching.cacheManager());
cuo.setName(ae.toString());

checkKeySourceConsistency(ae, caching.key(), caching.keyGenerator());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
*
* @author Costin Leau
* @author Phillip Webb
* @author Stephane Nicoll
*/
class CacheAdviceParser extends AbstractSingleBeanDefinitionParser {

Expand Down Expand Up @@ -186,6 +187,8 @@ private static class Props {

private String keyGenerator;

private String cacheManager;

private String condition;

private String method;
Expand All @@ -197,6 +200,7 @@ private static class Props {
String defaultCache = root.getAttribute("cache");
key = root.getAttribute("key");
keyGenerator = root.getAttribute("key-generator");
cacheManager = root.getAttribute("cache-manager");
condition = root.getAttribute("condition");
method = root.getAttribute(METHOD_ATTRIBUTE);

Expand All @@ -222,6 +226,7 @@ <T extends CacheOperation> T merge(Element element, ReaderContext readerCtx, T o

op.setKey(getAttributeValue(element, "key", this.key));
op.setKeyGenerator(getAttributeValue(element, "key-generator", this.keyGenerator));
op.setCacheManager(getAttributeValue(element, "cache-manager", this.cacheManager));
op.setCondition(getAttributeValue(element, "condition", this.condition));

if (StringUtils.hasText(op.getKey()) && StringUtils.hasText(op.getKeyGenerator())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,15 @@ public abstract class CacheAspectSupport implements InitializingBean, Applicatio


/**
* Set the CacheManager that this cache aspect should delegate to.
* Set the default {@link CacheManager} that this cache aspect should delegate to
* if no specific cache manager has been set for the operation.
*/
public void setCacheManager(CacheManager cacheManager) {
this.cacheManager = cacheManager;
}

/**
* Return the CacheManager that this cache aspect delegates to.
* Return the default {@link CacheManager} that this cache aspect delegates to.
*/
public CacheManager getCacheManager() {
return this.cacheManager;
Expand Down Expand Up @@ -164,14 +165,12 @@ protected String methodIdentification(Method method, Class<?> targetClass) {
return ClassUtils.getQualifiedMethodName(specificMethod);
}

protected Collection<? extends Cache> getCaches(CacheOperation operation) {
protected Collection<? extends Cache> getCaches(CacheOperation operation, CacheManager cacheManager) {
Set<String> cacheNames = operation.getCacheNames();
Collection<Cache> caches = new ArrayList<Cache>(cacheNames.size());
for (String cacheName : cacheNames) {
Cache cache = this.cacheManager.getCache(cacheName);
if (cache == null) {
throw new IllegalArgumentException("Cannot find cache named '" + cacheName + "' for " + operation);
}
Cache cache = cacheManager.getCache(cacheName);
Assert.notNull(cache, "Cannot find cache named '" + cacheName + "' for " + operation);
caches.add(cache);
}
return caches;
Expand Down Expand Up @@ -386,20 +385,29 @@ protected class CacheOperationContext {

private final KeyGenerator operationKeyGenerator;

private final CacheManager operationCacheManager;

public CacheOperationContext(CacheOperation operation, Method method,
Object[] args, Object target, Class<?> targetClass) {
this.operation = operation;
this.method = method;
this.args = extractArgs(method, args);
this.target = target;
this.targetClass = targetClass;
this.caches = CacheAspectSupport.this.getCaches(operation);
if (StringUtils.hasText(operation.getKeyGenerator())) { // TODO: exception mgt?
this.operationKeyGenerator = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
applicationContext, KeyGenerator.class, operation.getKeyGenerator());
} else {
this.operationKeyGenerator = keyGenerator;
}
if (StringUtils.hasText(operation.getCacheManager())) {
this.operationCacheManager = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
applicationContext, CacheManager.class, operation.getCacheManager());
}
else {
this.operationCacheManager = cacheManager;
}
this.caches = CacheAspectSupport.this.getCaches(operation, operationCacheManager);
}

private Object[] extractArgs(Method method, Object[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* Base class for cache operations.
*
* @author Costin Leau
* @author Stephane Nicoll
*/
public abstract class CacheOperation {

Expand All @@ -37,6 +38,8 @@ public abstract class CacheOperation {

private String keyGenerator = "";

private String cacheManager = "";

private String name = "";


Expand All @@ -56,6 +59,10 @@ public String getKeyGenerator() {
return keyGenerator;
}

public String getCacheManager() {
return cacheManager;
}

public String getName() {
return name;
}
Expand Down Expand Up @@ -88,6 +95,11 @@ public void setKeyGenerator(String keyGenerator) {
this.keyGenerator = keyGenerator;
}

public void setCacheManager(String cacheManager) {
Assert.notNull(cacheManager);
this.cacheManager = cacheManager;
}

public void setName(String name) {
Assert.hasText(name);
this.name = name;
Expand Down Expand Up @@ -137,6 +149,8 @@ protected StringBuilder getOperationDescription() {
result.append(this.key);
result.append("' | keyGenerator='");
result.append(this.keyGenerator);
result.append("' | cacheManager='");
result.append(this.cacheManager);
result.append("' | condition='");
result.append(this.condition);
result.append("'");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@
The name of the KeyGenerator bean responsible to compute the key, mutually exclusive with the key parameter.]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache-manager" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
The name of the CacheManager bean responsible to manage the operation.]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="condition" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Expand Down
Loading

0 comments on commit f06cad9

Please sign in to comment.