Use CacheResolver in Spring abstraction
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
This commit is contained in:
@@ -36,13 +36,11 @@ import org.springframework.context.annotation.Role;
|
||||
@Configuration
|
||||
public class AbstractJCacheConfiguration extends AbstractCachingConfiguration<JCacheConfigurer> {
|
||||
|
||||
protected CacheResolver cacheResolver;
|
||||
protected CacheResolver exceptionCacheResolver;
|
||||
|
||||
@Override
|
||||
protected void useCachingConfigurer(JCacheConfigurer config) {
|
||||
super.useCachingConfigurer(config);
|
||||
this.cacheResolver = config.cacheResolver();
|
||||
this.exceptionCacheResolver = config.exceptionCacheResolver();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,42 +21,25 @@ import org.springframework.cache.interceptor.CacheResolver;
|
||||
|
||||
/**
|
||||
* Extension of {@link CachingConfigurer} for the JSR-107 implementation.
|
||||
|
||||
* <p>To be implemented by classes annotated with @{@link org.springframework.cache.annotation.EnableCaching}
|
||||
* that wish or need to specify explicitly the {@link CacheResolver} bean(s) to be used for
|
||||
* annotation-driven cache management.
|
||||
*
|
||||
* <p>See @{@link org.springframework.cache.annotation.EnableCaching} for general examples and
|
||||
* context; see {@link #cacheResolver()} and {@link #exceptionCacheResolver()} for detailed
|
||||
* <p>To be implemented by classes annotated with
|
||||
* @{@link org.springframework.cache.annotation.EnableCaching} that wish or
|
||||
* need to specify explicitly how exception caches are resolved for
|
||||
* annotation-driven cache management. Consider extending {@link JCacheConfigurerSupport},
|
||||
* which provides a stub implementation of all interface methods.
|
||||
*
|
||||
* <p>See @{@link org.springframework.cache.annotation.EnableCaching} for
|
||||
* general examples and context; see {@link #exceptionCacheResolver()} for detailed
|
||||
* instructions.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
* @see CachingConfigurer
|
||||
* @see JCacheConfigurerSupport
|
||||
* @see org.springframework.cache.annotation.EnableCaching
|
||||
*/
|
||||
public interface JCacheConfigurer extends CachingConfigurer {
|
||||
|
||||
/**
|
||||
* Return the {@link CacheResolver} bean to use to resolve regular caches for
|
||||
* annotation-driven cache management. Implementations must explicitly declare
|
||||
* {@link org.springframework.context.annotation.Bean @Bean}, e.g.
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableCaching
|
||||
* public class AppConfig implements JCacheConfigurer {
|
||||
* @Bean // important!
|
||||
* @Override
|
||||
* public CacheResolver cacheResolver() {
|
||||
* // configure and return CacheResolver instance
|
||||
* }
|
||||
* // ...
|
||||
* }
|
||||
* </pre>
|
||||
* See {@link org.springframework.cache.annotation.EnableCaching} for more complete examples.
|
||||
*/
|
||||
CacheResolver cacheResolver();
|
||||
|
||||
/**
|
||||
* Return the {@link CacheResolver} bean to use to resolve exception caches for
|
||||
* annotation-driven cache management. Implementations must explicitly declare
|
||||
@@ -64,7 +47,7 @@ public interface JCacheConfigurer extends CachingConfigurer {
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableCaching
|
||||
* public class AppConfig implements JCacheConfigurer {
|
||||
* public class AppConfig extends JCacheConfigurerSupport {
|
||||
* @Bean // important!
|
||||
* @Override
|
||||
* public CacheResolver exceptionCacheResolver() {
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cache.jcache.config;
|
||||
|
||||
import org.springframework.cache.annotation.CachingConfigurerSupport;
|
||||
import org.springframework.cache.interceptor.CacheResolver;
|
||||
|
||||
/**
|
||||
* An extension of {@link CachingConfigurerSupport} that also implements
|
||||
* {@link JCacheConfigurer}.
|
||||
*
|
||||
* <p>Users of JSR-107 annotations may extend from this class rather than
|
||||
* implementing from {@link JCacheConfigurer} directly.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @since 4.1
|
||||
* @see JCacheConfigurer
|
||||
* @see CachingConfigurerSupport
|
||||
*/
|
||||
public class JCacheConfigurerSupport extends CachingConfigurerSupport implements JCacheConfigurer {
|
||||
|
||||
@Override
|
||||
public CacheResolver exceptionCacheResolver() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,13 +19,12 @@ package org.springframework.cache.jcache.interceptor;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.springframework.cache.Cache;
|
||||
import org.springframework.cache.CacheManager;
|
||||
import org.springframework.cache.interceptor.BaseCacheResolver;
|
||||
import org.springframework.cache.interceptor.BasicCacheOperation;
|
||||
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||
import org.springframework.cache.interceptor.CacheResolver;
|
||||
import org.springframework.cache.jcache.model.CacheResultOperation;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A simple {@link CacheResolver} that resolves the exception cache
|
||||
@@ -36,16 +35,14 @@ import org.springframework.util.Assert;
|
||||
* @since 4.1
|
||||
* @see org.springframework.cache.jcache.model.CacheResultOperation#getExceptionCacheName()
|
||||
*/
|
||||
public class SimpleExceptionCacheResolver implements CacheResolver {
|
||||
|
||||
private final CacheManager cacheManager;
|
||||
public class SimpleExceptionCacheResolver extends BaseCacheResolver {
|
||||
|
||||
public SimpleExceptionCacheResolver(CacheManager cacheManager) {
|
||||
this.cacheManager = cacheManager;
|
||||
super(cacheManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
|
||||
protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) {
|
||||
BasicCacheOperation operation = context.getOperation();
|
||||
if (!(operation instanceof CacheResultOperation)) {
|
||||
throw new IllegalStateException("Could not extract exception cache name from " + operation);
|
||||
@@ -53,9 +50,7 @@ public class SimpleExceptionCacheResolver implements CacheResolver {
|
||||
CacheResultOperation cacheResultOperation = (CacheResultOperation) operation;
|
||||
String exceptionCacheName = cacheResultOperation.getExceptionCacheName();
|
||||
if (exceptionCacheName != null) {
|
||||
Cache cache = cacheManager.getCache(exceptionCacheName);
|
||||
Assert.notNull(cache, "Cannot find cache named '" + exceptionCacheName + "' for " + operation);
|
||||
return Collections.singleton(cache);
|
||||
return Collections.singleton(exceptionCacheName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user