diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java index ff2b7ea75fd..74fe3f946f7 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/config/AbstractJCacheConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -18,6 +18,7 @@ package org.springframework.cache.jcache.config; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.cache.annotation.AbstractCachingConfiguration; +import org.springframework.cache.annotation.CachingConfigurer; import org.springframework.cache.interceptor.CacheResolver; import org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource; import org.springframework.cache.jcache.interceptor.JCacheOperationSource; @@ -34,14 +35,16 @@ import org.springframework.context.annotation.Role; * @see JCacheConfigurer */ @Configuration -public class AbstractJCacheConfiguration extends AbstractCachingConfiguration { +public class AbstractJCacheConfiguration extends AbstractCachingConfiguration { protected CacheResolver exceptionCacheResolver; @Override - protected void useCachingConfigurer(JCacheConfigurer config) { + protected void useCachingConfigurer(CachingConfigurer config) { super.useCachingConfigurer(config); - this.exceptionCacheResolver = config.exceptionCacheResolver(); + if (config instanceof JCacheConfigurer) { + this.exceptionCacheResolver = ((JCacheConfigurer) config).exceptionCacheResolver(); + } } @Bean(name = "jCacheOperationSource") diff --git a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java index bd5a1284495..d9dd6a5881c 100644 --- a/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java +++ b/spring-context-support/src/main/java/org/springframework/cache/jcache/interceptor/DefaultJCacheOperationSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -128,9 +128,9 @@ public class DefaultJCacheOperationSource extends AnnotationJCacheOperationSourc @Override public void afterSingletonsInstantiated() { - // Make sure those are initialized on startup... + // Make sure that the cache resolver is initialized. An exception cache resolver is only + // required if the exceptionCacheName attribute is set on an operation Assert.notNull(getDefaultCacheResolver(), "Cache resolver should have been initialized"); - Assert.notNull(getDefaultExceptionCacheResolver(), "Exception cache resolver should have been initialized"); } diff --git a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheJavaConfigTests.java b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheJavaConfigTests.java index d1fb35dde34..4b0c4a8f12b 100644 --- a/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheJavaConfigTests.java +++ b/spring-context-support/src/test/java/org/springframework/cache/jcache/config/JCacheJavaConfigTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -18,12 +18,15 @@ package org.springframework.cache.jcache.config; import java.util.Arrays; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.springframework.cache.Cache; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.concurrent.ConcurrentMapCache; +import org.springframework.cache.concurrent.ConcurrentMapCacheManager; import org.springframework.cache.config.SomeKeyGenerator; import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheResolver; @@ -35,7 +38,6 @@ import org.springframework.cache.interceptor.SimpleKeyGenerator; import org.springframework.cache.jcache.interceptor.AnnotatedJCacheableService; import org.springframework.cache.jcache.interceptor.DefaultJCacheOperationSource; import org.springframework.cache.jcache.interceptor.JCacheInterceptor; -import org.springframework.cache.jcache.interceptor.SimpleExceptionCacheResolver; import org.springframework.cache.support.NoOpCacheManager; import org.springframework.cache.support.SimpleCacheManager; import org.springframework.context.ApplicationContext; @@ -51,6 +53,9 @@ import static org.junit.Assert.*; */ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests { + @Rule + public final ExpectedException thrown = ExpectedException.none(); + @Override protected ApplicationContext getApplicationContext() { return new AnnotationConfigApplicationContext(EnableCachingConfig.class); @@ -80,10 +85,7 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests { assertEquals(SimpleCacheResolver.class, cos.getCacheResolver().getClass()); assertSame(context.getBean(CacheManager.class), ((SimpleCacheResolver) cos.getCacheResolver()).getCacheManager()); - assertNotNull(cos.getExceptionCacheResolver()); - assertEquals(SimpleExceptionCacheResolver.class, cos.getExceptionCacheResolver().getClass()); - assertSame(context.getBean(CacheManager.class), - ((SimpleExceptionCacheResolver) cos.getExceptionCacheResolver()).getCacheManager()); + assertNull(cos.getExceptionCacheResolver()); context.close(); } @@ -99,6 +101,28 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests { context.close(); } + @Test + public void exceptionCacheResolverFallbacksToMainOne() { + ConfigurableApplicationContext context = new AnnotationConfigApplicationContext( + NoExceptionCacheResolverConfig.class); + try { + DefaultJCacheOperationSource cos = context.getBean(DefaultJCacheOperationSource.class); + assertSame(context.getBean("cacheResolver"), cos.getCacheResolver()); + assertNull(cos.getExceptionCacheResolver()); + + JCacheableService service = context.getBean(JCacheableService.class); + + service.cache("id"); + + // This call requires the cache manager to be set + thrown.expect(IllegalStateException.class); + service.cacheWithException("test", false); + } + finally { + context.close(); + } + } + @Configuration @EnableCaching @@ -200,4 +224,20 @@ public class JCacheJavaConfigTests extends AbstractJCacheAnnotationTests { } } + @Configuration + @EnableCaching + static class NoExceptionCacheResolverConfig extends JCacheConfigurerSupport { + + @Override + @Bean + public CacheResolver cacheResolver() { + return new NamedCacheResolver(new ConcurrentMapCacheManager(), "default"); + } + + @Bean + public JCacheableService cacheableService() { + return new AnnotatedJCacheableService(new ConcurrentMapCache("default")); + } + } + } diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/AbstractCachingConfiguration.java b/spring-context/src/main/java/org/springframework/cache/annotation/AbstractCachingConfiguration.java index 4afb5ce6742..6ef7b0d95d1 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/AbstractCachingConfiguration.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/AbstractCachingConfiguration.java @@ -39,7 +39,7 @@ import org.springframework.util.CollectionUtils; * @see EnableCaching */ @Configuration -public abstract class AbstractCachingConfiguration implements ImportAware { +public abstract class AbstractCachingConfiguration implements ImportAware { protected AnnotationAttributes enableCaching; @@ -63,7 +63,7 @@ public abstract class AbstractCachingConfiguration } @Autowired(required = false) - void setConfigurers(Collection configurers) { + void setConfigurers(Collection configurers) { if (CollectionUtils.isEmpty(configurers)) { return; } @@ -73,14 +73,14 @@ public abstract class AbstractCachingConfiguration "Refactor the configuration such that CachingConfigurer is " + "implemented only once or not at all."); } - C configurer = configurers.iterator().next(); + CachingConfigurer configurer = configurers.iterator().next(); useCachingConfigurer(configurer); } /** * Extract the configuration from the nominated {@link CachingConfigurer}. */ - protected void useCachingConfigurer(C config) { + protected void useCachingConfigurer(CachingConfigurer config) { this.cacheManager = config.cacheManager(); this.cacheResolver = config.cacheResolver(); this.keyGenerator = config.keyGenerator(); diff --git a/spring-context/src/main/java/org/springframework/cache/annotation/ProxyCachingConfiguration.java b/spring-context/src/main/java/org/springframework/cache/annotation/ProxyCachingConfiguration.java index e05f13f0e5a..e6b2d48f5d6 100644 --- a/spring-context/src/main/java/org/springframework/cache/annotation/ProxyCachingConfiguration.java +++ b/spring-context/src/main/java/org/springframework/cache/annotation/ProxyCachingConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -35,7 +35,7 @@ import org.springframework.context.annotation.Role; * @see CachingConfigurationSelector */ @Configuration -public class ProxyCachingConfiguration extends AbstractCachingConfiguration { +public class ProxyCachingConfiguration extends AbstractCachingConfiguration { @Bean(name = CacheManagementConfigUtils.CACHE_ADVISOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE)