Add missing cache-resolver attribute
Prior to this commit, CacheResolver could not be configured through the XML namespace (i.e. cache:annotation-driven). This is now the case. Issue: SPR-11490
This commit is contained in:
parent
1338d46a6e
commit
9952973e01
|
@ -16,13 +16,15 @@
|
||||||
|
|
||||||
package org.springframework.cache.jcache.config;
|
package org.springframework.cache.jcache.config;
|
||||||
|
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.cache.interceptor.CacheErrorHandler;
|
import org.springframework.cache.interceptor.CacheErrorHandler;
|
||||||
|
import org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource;
|
||||||
import org.springframework.cache.jcache.interceptor.JCacheInterceptor;
|
import org.springframework.cache.jcache.interceptor.JCacheInterceptor;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.support.GenericXmlApplicationContext;
|
import org.springframework.context.support.GenericXmlApplicationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +38,16 @@ public class JCacheNamespaceDrivenTests extends AbstractJCacheAnnotationTests {
|
||||||
"/org/springframework/cache/jcache/config/jCacheNamespaceDriven.xml");
|
"/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
|
@Test
|
||||||
public void testCacheErrorHandler() {
|
public void testCacheErrorHandler() {
|
||||||
JCacheInterceptor ci = ctx.getBean(JCacheInterceptor.class);
|
JCacheInterceptor ci = ctx.getBean(JCacheInterceptor.class);
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?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:cache="http://www.springframework.org/schema/cache"
|
||||||
|
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">
|
||||||
|
|
||||||
|
<cache:annotation-driven cache-manager="cacheManager" cache-resolver="cacheResolver"/>
|
||||||
|
|
||||||
|
<!-- We can't hid the cache manager completely as the exception cache resolver needs it -->
|
||||||
|
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
|
||||||
|
<property name="caches">
|
||||||
|
<set>
|
||||||
|
<ref bean="defaultCache"/>
|
||||||
|
</set>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="defaultCache"
|
||||||
|
class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean">
|
||||||
|
<property name="name" value="default"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="cacheResolver" class="org.springframework.cache.interceptor.SimpleCacheResolver">
|
||||||
|
<property name="cacheManager" ref="cacheManager"/>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
|
||||||
|
</beans>
|
|
@ -42,7 +42,7 @@ public interface CachingConfigurer {
|
||||||
/**
|
/**
|
||||||
* Return the cache manager bean to use for annotation-driven cache
|
* Return the cache manager bean to use for annotation-driven cache
|
||||||
* management. A default {@link CacheResolver} will be initialized
|
* management. A default {@link CacheResolver} will be initialized
|
||||||
* behind the scene with this cache manager. For more fine-grained
|
* behind the scenes with this cache manager. For more fine-grained
|
||||||
* management of the cache resolution, consider setting the
|
* management of the cache resolution, consider setting the
|
||||||
* {@link CacheResolver} directly.
|
* {@link CacheResolver} directly.
|
||||||
* <p>Implementations must explicitly declare
|
* <p>Implementations must explicitly declare
|
||||||
|
@ -65,8 +65,10 @@ public interface CachingConfigurer {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the {@link CacheResolver} bean to use to resolve regular caches for
|
* Return the {@link CacheResolver} bean to use to resolve regular caches for
|
||||||
* annotation-driven cache management. This is an alternative option to set
|
* annotation-driven cache management. This is an alternative and more powerful
|
||||||
* the {@link CacheManager} to use.
|
* option of specifying the {@link CacheManager} to use.
|
||||||
|
* <p>If both a {@link #cacheManager()} and {@link #cacheResolver()} are set, the
|
||||||
|
* cache manager is ignored.
|
||||||
* <p>Implementations must explicitly declare
|
* <p>Implementations must explicitly declare
|
||||||
* {@link org.springframework.context.annotation.Bean @Bean}, e.g.
|
* {@link org.springframework.context.annotation.Bean @Bean}, e.g.
|
||||||
* <pre class="code">
|
* <pre class="code">
|
||||||
|
|
|
@ -98,10 +98,21 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void parseCacheManagerProperty(Element element, BeanDefinition def) {
|
/**
|
||||||
|
* 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",
|
def.getPropertyValues().add("cacheManager",
|
||||||
new RuntimeBeanReference(CacheNamespaceHandler.extractCacheManager(element)));
|
new RuntimeBeanReference(CacheNamespaceHandler.extractCacheManager(element)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static BeanDefinition parseErrorHandler(Element element, BeanDefinition def) {
|
private static BeanDefinition parseErrorHandler(Element element, BeanDefinition def) {
|
||||||
String name = element.getAttribute("error-handler");
|
String name = element.getAttribute("error-handler");
|
||||||
|
@ -130,7 +141,7 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
|
||||||
RootBeanDefinition interceptorDef = new RootBeanDefinition(CacheInterceptor.class);
|
RootBeanDefinition interceptorDef = new RootBeanDefinition(CacheInterceptor.class);
|
||||||
interceptorDef.setSource(eleSource);
|
interceptorDef.setSource(eleSource);
|
||||||
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||||
parseCacheManagerProperty(element, interceptorDef);
|
parseCacheResolution(element, interceptorDef, false);
|
||||||
parseErrorHandler(element, interceptorDef);
|
parseErrorHandler(element, interceptorDef);
|
||||||
CacheNamespaceHandler.parseKeyGenerator(element, interceptorDef);
|
CacheNamespaceHandler.parseKeyGenerator(element, interceptorDef);
|
||||||
interceptorDef.getPropertyValues().add("cacheOperationSources", new RuntimeBeanReference(sourceName));
|
interceptorDef.getPropertyValues().add("cacheOperationSources", new RuntimeBeanReference(sourceName));
|
||||||
|
@ -170,7 +181,7 @@ class AnnotationDrivenCacheBeanDefinitionParser implements BeanDefinitionParser
|
||||||
RootBeanDefinition def = new RootBeanDefinition();
|
RootBeanDefinition def = new RootBeanDefinition();
|
||||||
def.setBeanClassName(CACHE_ASPECT_CLASS_NAME);
|
def.setBeanClassName(CACHE_ASPECT_CLASS_NAME);
|
||||||
def.setFactoryMethodName("aspectOf");
|
def.setFactoryMethodName("aspectOf");
|
||||||
parseCacheManagerProperty(element, def);
|
parseCacheResolution(element, def, false);
|
||||||
CacheNamespaceHandler.parseKeyGenerator(element, def);
|
CacheNamespaceHandler.parseKeyGenerator(element, def);
|
||||||
parserContext.registerBeanComponent(new BeanComponentDefinition(def, CACHE_ASPECT_BEAN_NAME));
|
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);
|
RootBeanDefinition sourceDef = new RootBeanDefinition(JCACHE_OPERATION_SOURCE_CLASS);
|
||||||
sourceDef.setSource(eleSource);
|
sourceDef.setSource(eleSource);
|
||||||
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
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);
|
CacheNamespaceHandler.parseKeyGenerator(element, sourceDef);
|
||||||
return sourceDef;
|
return sourceDef;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,9 @@ import org.springframework.cache.CacheManager;
|
||||||
*/
|
*/
|
||||||
public class SimpleCacheResolver extends BaseCacheResolver {
|
public class SimpleCacheResolver extends BaseCacheResolver {
|
||||||
|
|
||||||
|
public SimpleCacheResolver() {
|
||||||
|
}
|
||||||
|
|
||||||
public SimpleCacheResolver(CacheManager cacheManager) {
|
public SimpleCacheResolver(CacheManager cacheManager) {
|
||||||
super(cacheManager);
|
super(cacheManager);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,10 @@
|
||||||
annotations on bean classes, and that proxies are automatically
|
annotations on bean classes, and that proxies are automatically
|
||||||
to be created for the relevant annotated beans.
|
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
|
See org.springframework.cache.annotation.EnableCaching Javadoc
|
||||||
for information on code-based alternatives to this XML element.
|
for information on code-based alternatives to this XML element.
|
||||||
|
@ -35,11 +38,15 @@
|
||||||
<xsd:attribute name="cache-manager" type="xsd:string" default="cacheManager">
|
<xsd:attribute name="cache-manager" type="xsd:string" default="cacheManager">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation source="java:org.springframework.cache.CacheManager"><![CDATA[
|
<xsd:documentation source="java:org.springframework.cache.CacheManager"><![CDATA[
|
||||||
The bean name of the CacheManager that is to be used to retrieve the backing caches.
|
The bean name of the CacheManager that is to be used to retrieve the backing
|
||||||
|
caches. 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.
|
||||||
|
|
||||||
This attribute is not required, and only needs to be specified
|
Note that this attribute is still mandatory if you are using JSR-107 as an
|
||||||
explicitly if the bean name of the desired CacheManager
|
additional exception cache resolver should be created and requires a CacheManager
|
||||||
is not 'cacheManager'.
|
to do so.
|
||||||
]]></xsd:documentation>
|
]]></xsd:documentation>
|
||||||
<xsd:appinfo>
|
<xsd:appinfo>
|
||||||
<tool:annotation kind="ref">
|
<tool:annotation kind="ref">
|
||||||
|
@ -48,6 +55,21 @@
|
||||||
</xsd:appinfo>
|
</xsd:appinfo>
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
</xsd:attribute>
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="cache-resolver" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation source="java:org.springframework.cache.interceptor.CacheResolver"><![CDATA[
|
||||||
|
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. See the javadoc of CacheResolver for more details.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
<xsd:appinfo>
|
||||||
|
<tool:annotation kind="ref">
|
||||||
|
<tool:expected-type type="org.springframework.cache.interceptor.CacheResolver"/>
|
||||||
|
</tool:annotation>
|
||||||
|
</xsd:appinfo>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
<xsd:attribute name="key-generator" type="xsd:string">
|
<xsd:attribute name="key-generator" type="xsd:string">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation source="java:org.springframework.cache.interceptor.KeyGenerator"><![CDATA[
|
<xsd:documentation source="java:org.springframework.cache.interceptor.KeyGenerator"><![CDATA[
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.springframework.context.support.GenericXmlApplicationContext;
|
||||||
/**
|
/**
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @author Chris Beams
|
* @author Chris Beams
|
||||||
|
* @author Stephane Nicoll
|
||||||
*/
|
*/
|
||||||
public class AnnotationNamespaceDrivenTests extends AbstractAnnotationTests {
|
public class AnnotationNamespaceDrivenTests extends AbstractAnnotationTests {
|
||||||
|
|
||||||
|
@ -44,6 +45,26 @@ public class AnnotationNamespaceDrivenTests extends AbstractAnnotationTests {
|
||||||
assertSame(ctx.getBean("keyGenerator"), ci.getKeyGenerator());
|
assertSame(ctx.getBean("keyGenerator"), ci.getKeyGenerator());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cacheResolver() {
|
||||||
|
ConfigurableApplicationContext context = new GenericXmlApplicationContext(
|
||||||
|
"/org/springframework/cache/config/annotationDrivenCacheNamespace-resolver.xml");
|
||||||
|
|
||||||
|
CacheInterceptor ci = context.getBean(CacheInterceptor.class);
|
||||||
|
assertSame(context.getBean("cacheResolver"), ci.getCacheResolver());
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void bothSetOnlyResolverIsUsed() {
|
||||||
|
ConfigurableApplicationContext context = new GenericXmlApplicationContext(
|
||||||
|
"/org/springframework/cache/config/annotationDrivenCacheNamespace-manager-resolver.xml");
|
||||||
|
|
||||||
|
CacheInterceptor ci = context.getBean(CacheInterceptor.class);
|
||||||
|
assertSame(context.getBean("cacheResolver"), ci.getCacheResolver());
|
||||||
|
context.close();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCacheErrorHandler() {
|
public void testCacheErrorHandler() {
|
||||||
CacheInterceptor ci = ctx.getBean("org.springframework.cache.interceptor.CacheInterceptor#0",
|
CacheInterceptor ci = ctx.getBean("org.springframework.cache.interceptor.CacheInterceptor#0",
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?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:cache="http://www.springframework.org/schema/cache"
|
||||||
|
xmlns:p="http://www.springframework.org/schema/p"
|
||||||
|
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">
|
||||||
|
|
||||||
|
<cache:annotation-driven cache-manager="customCacheManager"
|
||||||
|
cache-resolver="cacheResolver"/>
|
||||||
|
|
||||||
|
<bean id="customCacheManager" class="org.springframework.cache.support.SimpleCacheManager">
|
||||||
|
<property name="caches">
|
||||||
|
<set>
|
||||||
|
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
|
||||||
|
</set>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="cacheResolver" class="org.springframework.cache.interceptor.SimpleCacheResolver">
|
||||||
|
<property name="cacheManager" ref="customCacheManager"/>
|
||||||
|
</bean>
|
||||||
|
</beans>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?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:cache="http://www.springframework.org/schema/cache"
|
||||||
|
xmlns:p="http://www.springframework.org/schema/p"
|
||||||
|
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">
|
||||||
|
|
||||||
|
<cache:annotation-driven cache-resolver="cacheResolver"/>
|
||||||
|
|
||||||
|
<bean id="cacheResolver" class="org.springframework.cache.interceptor.SimpleCacheResolver">
|
||||||
|
<property name="cacheManager">
|
||||||
|
<bean class="org.springframework.cache.support.SimpleCacheManager">
|
||||||
|
<property name="caches">
|
||||||
|
<set>
|
||||||
|
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
|
||||||
|
p:name="default"/>
|
||||||
|
</set>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</beans>
|
|
@ -47193,8 +47193,17 @@ application through AOP. The configuration is intentionally similar with that of
|
||||||
| `cache-manager`
|
| `cache-manager`
|
||||||
| N/A (See `CachingConfigurer` javadocs)
|
| N/A (See `CachingConfigurer` javadocs)
|
||||||
| cacheManager
|
| cacheManager
|
||||||
| Name of cache manager to use. Only required if the name of the cache manager is not
|
| Name of cache manager to use. A default `CacheResolver` will be initialized behind
|
||||||
`cacheManager`.
|
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`
|
| `key-generator`
|
||||||
| N/A (See `CachingConfigurer` javadocs)
|
| N/A (See `CachingConfigurer` javadocs)
|
||||||
|
|
Loading…
Reference in New Issue