Lazily resolve the default exception CacheResolver
This is a rework of 314b069
that may still lead to issue if a Cacheable
annotated bean is inspected on startup. Instead of resolving the default
exception CacheResolver if a cache operation is parsed, we resolve it as
late as possible (i.e. when an exception is thrown and the relevant
exception cache needs to be resolved)
Issue: SPR-12850
This commit is contained in:
parent
867971de89
commit
a7fec6a459
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.cache.jcache.interceptor;
|
package org.springframework.cache.jcache.interceptor;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
import org.springframework.beans.factory.BeanFactoryAware;
|
||||||
|
@ -23,7 +25,9 @@ import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||||
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
|
||||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||||
|
import org.springframework.cache.Cache;
|
||||||
import org.springframework.cache.CacheManager;
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.interceptor.CacheOperationInvocationContext;
|
||||||
import org.springframework.cache.interceptor.CacheResolver;
|
import org.springframework.cache.interceptor.CacheResolver;
|
||||||
import org.springframework.cache.interceptor.KeyGenerator;
|
import org.springframework.cache.interceptor.KeyGenerator;
|
||||||
import org.springframework.cache.interceptor.SimpleCacheResolver;
|
import org.springframework.cache.interceptor.SimpleCacheResolver;
|
||||||
|
@ -179,7 +183,7 @@ public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSourc
|
||||||
@Override
|
@Override
|
||||||
protected CacheResolver getDefaultExceptionCacheResolver() {
|
protected CacheResolver getDefaultExceptionCacheResolver() {
|
||||||
if (this.exceptionCacheResolver == null) {
|
if (this.exceptionCacheResolver == null) {
|
||||||
this.exceptionCacheResolver = new SimpleExceptionCacheResolver(getDefaultCacheManager());
|
this.exceptionCacheResolver = new LazyCacheResolver();
|
||||||
}
|
}
|
||||||
return this.exceptionCacheResolver;
|
return this.exceptionCacheResolver;
|
||||||
}
|
}
|
||||||
|
@ -189,4 +193,29 @@ public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSourc
|
||||||
return this.adaptedKeyGenerator;
|
return this.adaptedKeyGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only resolve the default exception cache resolver when an exception needs to be handled.
|
||||||
|
* <p>
|
||||||
|
* A non-JSR-107 setup requires either a {@link CacheManager} or a {@link CacheResolver}. If only
|
||||||
|
* the latter is specified, it is not possible to extract a default exception {@code CacheResolver}
|
||||||
|
* from a custom {@code CacheResolver} implementation so we have to fallback on the {@code CacheManager}.
|
||||||
|
* <p>
|
||||||
|
* This gives this weird situation of a perfectly valid configuration that breaks all the sudden
|
||||||
|
* because the JCache support is enabled. To avoid this we resolve the default exception {@code CacheResolver}
|
||||||
|
* as late as possible to avoid such hard requirement in other cases.
|
||||||
|
*/
|
||||||
|
class LazyCacheResolver implements CacheResolver {
|
||||||
|
|
||||||
|
private CacheResolver cacheResolver;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends Cache> resolveCaches(CacheOperationInvocationContext<?> context) {
|
||||||
|
if (this.cacheResolver == null) {
|
||||||
|
this.cacheResolver = new SimpleExceptionCacheResolver(getDefaultCacheManager());
|
||||||
|
}
|
||||||
|
return this.cacheResolver.resolveCaches(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,7 +102,7 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void exceptionCacheResolverFallbacksToMainOne() {
|
public void exceptionCacheResolverLazilyRequired() {
|
||||||
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
|
ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
|
||||||
NoExceptionCacheResolverConfig.class);
|
NoExceptionCacheResolverConfig.class);
|
||||||
try {
|
try {
|
||||||
|
|
Loading…
Reference in New Issue