Prior to this commit, the CacheResolver was not used by Spring's
caching abstraction. This commit provides the necessary configuration
options to tune how a cache is resolved for a given operation.
CacheResolver can be customized globally, at the operation level or at
the class level. This breaks the CachingConfigurer class and a support
implementation is provided that implements all methods so that the
default is taken if it's not overridden. The JSR-107 support has been
updated as well, with a similar support class.
In particular, the static and runtime information of a cache
operation were mixed which prevents any forms of caching. As the
CacheResolver and the KeyGenerator can be customized, every operation
call lead to a lookup in the context for the bean.
This commit adds CacheOperationMetadata, a static holder of all
the non-runtime metadata about a cache operation. This is used
as an input source for the existing CacheOperationContext.
Caching the operation metadata in an AspectJ aspect can have side
effects as the aspect is static instance for the current ClassLoader.
The metadata cache needs to be cleared when the context shutdowns.
This is essentially a test issue only as in practice each application
runs in its class loader. Tests are now closing the context properly
to honor the DisposableBean callback.
Issue: SPR-11490
@ -35,7 +35,7 @@ public class AspectJAnnotationTests extends AbstractAnnotationTests {
@@ -35,7 +35,7 @@ public class AspectJAnnotationTests extends AbstractAnnotationTests {
thrownewIllegalStateException("Could not extract exception cache name from "+operation);
@ -53,9 +50,7 @@ public class SimpleExceptionCacheResolver implements CacheResolver {
@@ -53,9 +50,7 @@ public class SimpleExceptionCacheResolver implements CacheResolver {
@ -61,6 +65,35 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
@@ -61,6 +65,35 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
@ -118,4 +151,42 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
@@ -118,4 +151,42 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
@ -45,7 +41,7 @@ public class JCacheInterceptorTests extends AbstractJCacheTests {
@@ -45,7 +41,7 @@ public class JCacheInterceptorTests extends AbstractJCacheTests {
@ -65,7 +61,7 @@ public class JCacheInterceptorTests extends AbstractJCacheTests {
@@ -65,7 +61,7 @@ public class JCacheInterceptorTests extends AbstractJCacheTests {
@ -132,25 +128,6 @@ public class JCacheInterceptorTests extends AbstractJCacheTests {
@@ -132,25 +128,6 @@ public class JCacheInterceptorTests extends AbstractJCacheTests {
@ -46,6 +47,8 @@ public abstract class AbstractCachingConfiguration<C extends CachingConfigurer>
@@ -46,6 +47,8 @@ public abstract class AbstractCachingConfiguration<C extends CachingConfigurer>
protectedCacheManagercacheManager;
protectedCacheResolvercacheResolver;
protectedKeyGeneratorkeyGenerator;
@Autowired(required=false)
@ -86,7 +89,7 @@ public abstract class AbstractCachingConfiguration<C extends CachingConfigurer>
@@ -86,7 +89,7 @@ public abstract class AbstractCachingConfiguration<C extends CachingConfigurer>
thrownewIllegalStateException(nManagers+" beans of type CacheManager "+
@ -98,7 +101,7 @@ public abstract class AbstractCachingConfiguration<C extends CachingConfigurer>
@@ -98,7 +101,7 @@ public abstract class AbstractCachingConfiguration<C extends CachingConfigurer>
// keyGenerator remains null; will fall back to default within CacheInterceptor
}
else{
if(this.cacheManager==null){
thrownewIllegalStateException("No bean of type CacheManager could be found. "+
"Register a CacheManager bean or remove the @EnableCaching annotation "+
"from your configuration.");
@ -110,6 +113,7 @@ public abstract class AbstractCachingConfiguration<C extends CachingConfigurer>
@@ -110,6 +113,7 @@ public abstract class AbstractCachingConfiguration<C extends CachingConfigurer>
@ -59,7 +59,10 @@ public class ProxyCachingConfiguration extends AbstractCachingConfiguration<Cach
@@ -59,7 +59,10 @@ public class ProxyCachingConfiguration extends AbstractCachingConfiguration<Cach
@ -105,6 +105,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@@ -105,6 +105,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
cuo.setKey(caching.key());
cuo.setKeyGenerator(caching.keyGenerator());
cuo.setCacheManager(caching.cacheManager());
cuo.setCacheResolver(caching.cacheResolver());
cuo.setName(ae.toString());
defaultConfig.applyDefault(cuo);
@ -121,6 +122,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@@ -121,6 +122,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@ -140,6 +142,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@@ -140,6 +142,7 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
cuo.setKey(caching.key());
cuo.setKeyGenerator(caching.keyGenerator());
cuo.setCacheManager(caching.cacheManager());
cuo.setCacheResolver(caching.cacheResolver());
cuo.setName(ae.toString());
defaultConfig.applyDefault(cuo);
@ -186,8 +189,8 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@@ -186,8 +189,8 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@ -228,9 +231,16 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@@ -228,9 +231,16 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
"These attributes are mutually exclusive: either set the SpEL expression used to"+
"compute the key at runtime or set the name of the KeyGenerator bean to use.");
thrownewIllegalStateException("Invalid cache annotation configuration on '"
+ae.toString()+"'. Both 'cacheManager' and 'cacheResolver' attributes have been set. "+
"These attributes are mutually exclusive: the cache manager is used to configure a"+
"default cache resolver if none is set. If a cache resolver is set, the cache manager"+
"won't be used.");
}
if(operation.getCacheNames().isEmpty()){
thrownewIllegalStateException("No cache names could be detected on '"
+ae.toString()+"'. Make sure to set the value parameter on the annotation or"+
+ae.toString()+"'. Make sure to set the value parameter on the annotation or"+
"declare a @CacheConfig at the class-level with the default cache name(s) to use.");
}
}
@ -245,22 +255,29 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@@ -245,22 +255,29 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@ -269,17 +286,29 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@@ -269,17 +286,29 @@ public class SpringCacheAnnotationParser implements CacheAnnotationParser, Seria
@ -39,4 +39,5 @@ public class CacheAdviceNamespaceTests extends AbstractAnnotationTests {
@@ -39,4 +39,5 @@ public class CacheAdviceNamespaceTests extends AbstractAnnotationTests {
@ -46,7 +45,7 @@ public class EnableCachingTests extends AbstractAnnotationTests {
@@ -46,7 +45,7 @@ public class EnableCachingTests extends AbstractAnnotationTests {
@ -111,19 +110,38 @@ public class EnableCachingTests extends AbstractAnnotationTests {
@@ -111,19 +110,38 @@ public class EnableCachingTests extends AbstractAnnotationTests {
@ -149,9 +167,7 @@ public class EnableCachingTests extends AbstractAnnotationTests {
@@ -149,9 +167,7 @@ public class EnableCachingTests extends AbstractAnnotationTests {
@ -182,7 +198,7 @@ public class EnableCachingTests extends AbstractAnnotationTests {
@@ -182,7 +198,7 @@ public class EnableCachingTests extends AbstractAnnotationTests {
@ -197,4 +213,37 @@ public class EnableCachingTests extends AbstractAnnotationTests {
@@ -197,4 +213,37 @@ public class EnableCachingTests extends AbstractAnnotationTests {