diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheNamespaceDrivenTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheNamespaceDrivenTests.java
index 7391c8661d..0cdef3f159 100644
--- a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheNamespaceDrivenTests.java
+++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheNamespaceDrivenTests.java
@@ -16,13 +16,15 @@
package org.springframework.cache.jcache.config;
-import static org.junit.Assert.assertSame;
+import static org.junit.Assert.*;
import org.junit.Test;
import org.springframework.cache.interceptor.CacheErrorHandler;
+import org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource;
import org.springframework.cache.jcache.interceptor.JCacheInterceptor;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
/**
@@ -36,6 +38,16 @@ public class JCacheNamespaceDrivenTests extends AbstractJCacheAnnotationTests {
"/org/springframework/cache/jcache/config/jCacheNamespaceDriven.xml");
}
+ @Test
+ public void cacheResolver() {
+ ConfigurableApplicationContext context = new GenericXmlApplicationContext(
+ "/org/springframework/cache/jcache/config/jCacheNamespaceDriven-resolver.xml");
+
+ DefaultJCacheOperationSource ci = context.getBean(DefaultJCacheOperationSource.class);
+ assertSame(context.getBean("cacheResolver"), ci.getDefaultCacheResolver());
+ context.close();
+ }
+
@Test
public void testCacheErrorHandler() {
JCacheInterceptor ci = ctx.getBean(JCacheInterceptor.class);
diff --git a/spring-context-support/src/test/resources/org/springframework/cache/jcache/config/jCacheNamespaceDriven-resolver.xml b/spring-context-support/src/test/resources/org/springframework/cache/jcache/config/jCacheNamespaceDriven-resolver.xml
new file mode 100644
index 0000000000..9c3c96360d
--- /dev/null
+++ b/spring-context-support/src/test/resources/org/springframework/cache/jcache/config/jCacheNamespaceDriven-resolver.xml
@@ -0,0 +1,31 @@
+
+
Implementations must explicitly declare @@ -65,8 +65,10 @@ public interface CachingConfigurer { /** * Return the {@link CacheResolver} bean to use to resolve regular caches for - * annotation-driven cache management. This is an alternative option to set - * the {@link CacheManager} to use. + * annotation-driven cache management. This is an alternative and more powerful + * option of specifying the {@link CacheManager} to use. + *
If both a {@link #cacheManager()} and {@link #cacheResolver()} are set, the + * cache manager is ignored. *
Implementations must explicitly declare * {@link org.springframework.context.annotation.Bean @Bean}, e.g. *
diff --git a/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java b/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java
index 5621d5a635..c3fad09bcf 100644
--- a/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java
+++ b/spring-context/src/main/java/org/springframework/cache/config/AnnotationDrivenCacheBeanDefinitionParser.java
@@ -98,9 +98,20 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
}
}
- private static void parseCacheManagerProperty(Element element, BeanDefinition def) {
- def.getPropertyValues().add("cacheManager",
- new RuntimeBeanReference(CacheNamespaceHandler.extractCacheManager(element)));
+ /**
+ * Parse the cache resolution strategy to use. If a 'cache-resolver' attribute
+ * is set, it is injected. Otherwise the 'cache-manager' is set. If {@code setBoth}
+ * is {@code true}, both service are actually injected.
+ */
+ private static void parseCacheResolution(Element element, BeanDefinition def, boolean setBoth) {
+ String name = element.getAttribute("cache-resolver");
+ if (StringUtils.hasText(name)) {
+ def.getPropertyValues().add("cacheResolver", new RuntimeBeanReference(name.trim()));
+ }
+ if (!StringUtils.hasText(name) || setBoth) {
+ def.getPropertyValues().add("cacheManager",
+ new RuntimeBeanReference(CacheNamespaceHandler.extractCacheManager(element)));
+ }
}
private static BeanDefinition parseErrorHandler(Element element, BeanDefinition def) {
@@ -130,7 +141,7 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
RootBeanDefinition interceptorDef = new RootBeanDefinition(CacheInterceptor.class);
interceptorDef.setSource(eleSource);
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- parseCacheManagerProperty(element, interceptorDef);
+ parseCacheResolution(element, interceptorDef, false);
parseErrorHandler(element, interceptorDef);
CacheNamespaceHandler.parseKeyGenerator(element, interceptorDef);
interceptorDef.getPropertyValues().add("cacheOperationSources", new RuntimeBeanReference(sourceName));
@@ -170,7 +181,7 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
RootBeanDefinition def = new RootBeanDefinition();
def.setBeanClassName(CACHE_ASPECT_CLASS_NAME);
def.setFactoryMethodName("aspectOf");
- parseCacheManagerProperty(element, def);
+ parseCacheResolution(element, def, false);
CacheNamespaceHandler.parseKeyGenerator(element, def);
parserContext.registerBeanComponent(new BeanComponentDefinition(def, CACHE_ASPECT_BEAN_NAME));
}
@@ -239,7 +250,9 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
RootBeanDefinition sourceDef = new RootBeanDefinition(JCACHE_OPERATION_SOURCE_CLASS);
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
- parseCacheManagerProperty(element, sourceDef);
+ // JSR-107 support should create an exception cache resolver with the cache manager
+ // and there is no way to set that exception cache resolver from the namespace
+ parseCacheResolution(element, sourceDef, true);
CacheNamespaceHandler.parseKeyGenerator(element, sourceDef);
return sourceDef;
}
diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java
index 353de00c6f..7eb01e19bf 100644
--- a/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java
+++ b/spring-context/src/main/java/org/springframework/cache/interceptor/SimpleCacheResolver.java
@@ -32,6 +32,9 @@ import org.springframework.cache.CacheManager;
*/
public class SimpleCacheResolver extends BaseCacheResolver {
+ public SimpleCacheResolver() {
+ }
+
public SimpleCacheResolver(CacheManager cacheManager) {
super(cacheManager);
}
diff --git a/spring-context/src/main/resources/org/springframework/cache/config/spring-cache-4.1.xsd b/spring-context/src/main/resources/org/springframework/cache/config/spring-cache-4.1.xsd
index 9c6b547c9e..66104b98db 100644
--- a/spring-context/src/main/resources/org/springframework/cache/config/spring-cache-4.1.xsd
+++ b/spring-context/src/main/resources/org/springframework/cache/config/spring-cache-4.1.xsd
@@ -26,7 +26,10 @@
annotations on bean classes, and that proxies are automatically
to be created for the relevant annotated beans.
- The default annotations supported are Spring's @Cacheable and @CacheEvict.
+ The default annotations supported are Spring's @Cacheable, @CachePut and @CacheEvict. If
+ spring-context-support and the JSR-107 API are on the classpath, additional proxies are
+ automatically created for JSR-107 annotated beans, that is @CacheResult, @CachePut,
+ @CacheRemove and @CacheRemoveAll.
See org.springframework.cache.annotation.EnableCaching Javadoc
for information on code-based alternatives to this XML element.
@@ -35,11 +38,15 @@
@@ -48,6 +55,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/spring-context/src/test/resources/org/springframework/cache/config/annotationDrivenCacheNamespace-resolver.xml b/spring-context/src/test/resources/org/springframework/cache/config/annotationDrivenCacheNamespace-resolver.xml
new file mode 100644
index 0000000000..013111799c
--- /dev/null
+++ b/spring-context/src/test/resources/org/springframework/cache/config/annotationDrivenCacheNamespace-resolver.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/asciidoc/index.adoc b/src/asciidoc/index.adoc
index d33faa527c..8727790c23 100644
--- a/src/asciidoc/index.adoc
+++ b/src/asciidoc/index.adoc
@@ -47193,8 +47193,17 @@ application through AOP. The configuration is intentionally similar with that of
| `cache-manager`
| N/A (See `CachingConfigurer` javadocs)
| cacheManager
-| Name of cache manager to use. Only required if the name of the cache manager is not
- `cacheManager`.
+| Name of cache manager to use. A default `CacheResolver` will be initialized behind
+ the scenes with this cache manager (or `cacheManager`if not set). For more
+ fine-grained management of the cache resolution, consider setting the 'cache-resolver'
+ attribute.
+
+| `cache-resolver`
+| N/A (See `CachingConfigurer` javadocs)
+| A `SimpleCacheResolver` using the configured `cacheManager`.
+| The bean name of the CacheResolver that is to be used to resolve the backing caches.
+ This attribute is not required, and only needs to be specified as an alternative to
+ the 'cache-manager' attribute.
| `key-generator`
| N/A (See `CachingConfigurer` javadocs)