Skip to content

Commit 6cd85dd

Browse files
committed
Align caching AspectJ configuration
The `CacheResolver` and `ErrorHandler` features introduced in 4.1 were not properly enabled in AspectJ mode. This commit adds more tests from the regular proxy-based mode and align the AspectJ caching configuration. Issue: SPR-14413
1 parent 775ffbe commit 6cd85dd

File tree

6 files changed

+396
-10
lines changed

6 files changed

+396
-10
lines changed

spring-aspects/src/main/java/org/springframework/cache/aspectj/AspectJCachingConfiguration.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -39,12 +39,18 @@ public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
3939
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
4040
public AnnotationCacheAspect cacheAspect() {
4141
AnnotationCacheAspect cacheAspect = AnnotationCacheAspect.aspectOf();
42-
if (this.cacheManager != null) {
42+
if (this.cacheResolver != null) {
43+
cacheAspect.setCacheResolver(this.cacheResolver);
44+
}
45+
else if (this.cacheManager != null) {
4346
cacheAspect.setCacheManager(this.cacheManager);
4447
}
4548
if (this.keyGenerator != null) {
4649
cacheAspect.setKeyGenerator(this.keyGenerator);
4750
}
51+
if (this.errorHandler != null) {
52+
cacheAspect.setErrorHandler(this.errorHandler);
53+
}
4854
return cacheAspect;
4955
}
5056

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
/*
2+
* Copyright 2002-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.cache.aspectj;
18+
19+
import org.junit.After;
20+
import org.junit.Ignore;
21+
import org.junit.Test;
22+
23+
import org.springframework.beans.factory.BeanCreationException;
24+
import org.springframework.cache.CacheManager;
25+
import org.springframework.cache.CacheTestUtils;
26+
import org.springframework.cache.annotation.CachingConfigurerSupport;
27+
import org.springframework.cache.annotation.EnableCaching;
28+
import org.springframework.cache.config.AnnotatedClassCacheableService;
29+
import org.springframework.cache.config.CacheableService;
30+
import org.springframework.cache.config.DefaultCacheableService;
31+
import org.springframework.cache.config.SomeCustomKeyGenerator;
32+
import org.springframework.cache.config.SomeKeyGenerator;
33+
import org.springframework.cache.interceptor.CacheErrorHandler;
34+
import org.springframework.cache.interceptor.CacheInterceptor;
35+
import org.springframework.cache.interceptor.CacheResolver;
36+
import org.springframework.cache.interceptor.KeyGenerator;
37+
import org.springframework.cache.interceptor.NamedCacheResolver;
38+
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
39+
import org.springframework.cache.interceptor.SimpleCacheResolver;
40+
import org.springframework.cache.support.NoOpCacheManager;
41+
import org.springframework.context.ConfigurableApplicationContext;
42+
import org.springframework.context.annotation.AdviceMode;
43+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
44+
import org.springframework.context.annotation.Bean;
45+
import org.springframework.context.annotation.Configuration;
46+
47+
import static org.junit.Assert.*;
48+
49+
/**
50+
*
51+
* @author Stephane Nicoll
52+
*/
53+
public class AspectJEnableCachingIsolatedTests {
54+
55+
private ConfigurableApplicationContext ctx;
56+
57+
@After
58+
public void closeContext() {
59+
if (this.ctx != null) {
60+
this.ctx.close();
61+
}
62+
}
63+
64+
@Test
65+
public void testKeyStrategy() {
66+
load(EnableCachingConfig.class);
67+
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
68+
assertSame(this.ctx.getBean("keyGenerator", KeyGenerator.class), aspect.getKeyGenerator());
69+
}
70+
71+
@Test
72+
public void testCacheErrorHandler() {
73+
load(EnableCachingConfig.class);
74+
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
75+
assertSame(this.ctx.getBean("errorHandler", CacheErrorHandler.class), aspect.getErrorHandler());
76+
}
77+
78+
// --- local tests -------
79+
80+
@Test
81+
public void singleCacheManagerBean() throws Throwable {
82+
load(SingleCacheManagerConfig.class);
83+
}
84+
85+
@Test(expected = IllegalStateException.class)
86+
public void multipleCacheManagerBeans() throws Throwable {
87+
try {
88+
load(MultiCacheManagerConfig.class);
89+
}
90+
catch (BeanCreationException ex) {
91+
Throwable root = ex.getRootCause();
92+
assertTrue(root.getMessage().contains("beans of type CacheManager"));
93+
throw root;
94+
}
95+
}
96+
97+
@Test
98+
public void multipleCacheManagerBeans_implementsCachingConfigurer() {
99+
load(MultiCacheManagerConfigurer.class); // does not throw
100+
}
101+
102+
@Test(expected = IllegalStateException.class)
103+
public void multipleCachingConfigurers() throws Throwable {
104+
try {
105+
load(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
106+
}
107+
catch (BeanCreationException ex) {
108+
Throwable root = ex.getRootCause();
109+
assertTrue(root.getMessage().contains("implementations of CachingConfigurer"));
110+
throw root;
111+
}
112+
}
113+
114+
@Test(expected = IllegalStateException.class)
115+
public void noCacheManagerBeans() throws Throwable {
116+
try {
117+
load(EmptyConfig.class);
118+
}
119+
catch (BeanCreationException ex) {
120+
Throwable root = ex.getRootCause();
121+
assertTrue(root.getMessage().contains("No bean of type CacheManager"));
122+
throw root;
123+
}
124+
}
125+
126+
@Test
127+
@Ignore("AspectJ has some sort of caching that makes this one fail")
128+
public void emptyConfigSupport() {
129+
load(EmptyConfigSupportConfig.class);
130+
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
131+
assertNotNull(aspect.getCacheResolver());
132+
assertEquals(SimpleCacheResolver.class, aspect.getCacheResolver().getClass());
133+
assertSame(this.ctx.getBean(CacheManager.class),
134+
((SimpleCacheResolver) aspect.getCacheResolver()).getCacheManager());
135+
}
136+
137+
@Test
138+
public void bothSetOnlyResolverIsUsed() {
139+
load(FullCachingConfig.class);
140+
141+
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
142+
assertSame(this.ctx.getBean("cacheResolver"), aspect.getCacheResolver());
143+
assertSame(this.ctx.getBean("keyGenerator"), aspect.getKeyGenerator());
144+
}
145+
146+
private void load(Class<?>... config) {
147+
this.ctx = new AnnotationConfigApplicationContext(config);
148+
}
149+
150+
151+
@Configuration
152+
@EnableCaching(mode = AdviceMode.ASPECTJ)
153+
static class EnableCachingConfig extends CachingConfigurerSupport {
154+
155+
@Override
156+
@Bean
157+
public CacheManager cacheManager() {
158+
return CacheTestUtils.createSimpleCacheManager("testCache", "primary", "secondary");
159+
}
160+
161+
@Bean
162+
public CacheableService<?> service() {
163+
return new DefaultCacheableService();
164+
}
165+
166+
@Bean
167+
public CacheableService<?> classService() {
168+
return new AnnotatedClassCacheableService();
169+
}
170+
171+
@Override
172+
@Bean
173+
public KeyGenerator keyGenerator() {
174+
return new SomeKeyGenerator();
175+
}
176+
177+
@Override
178+
@Bean
179+
public CacheErrorHandler errorHandler() {
180+
return new SimpleCacheErrorHandler();
181+
}
182+
183+
@Bean
184+
public KeyGenerator customKeyGenerator() {
185+
return new SomeCustomKeyGenerator();
186+
}
187+
188+
@Bean
189+
public CacheManager customCacheManager() {
190+
return CacheTestUtils.createSimpleCacheManager("testCache");
191+
}
192+
}
193+
194+
195+
@Configuration
196+
@EnableCaching(mode = AdviceMode.ASPECTJ)
197+
static class EmptyConfig {
198+
}
199+
200+
201+
@Configuration
202+
@EnableCaching(mode = AdviceMode.ASPECTJ)
203+
static class SingleCacheManagerConfig {
204+
205+
@Bean
206+
public CacheManager cm1() {
207+
return new NoOpCacheManager();
208+
}
209+
}
210+
211+
212+
@Configuration
213+
@EnableCaching(mode = AdviceMode.ASPECTJ)
214+
static class MultiCacheManagerConfig {
215+
216+
@Bean
217+
public CacheManager cm1() {
218+
return new NoOpCacheManager();
219+
}
220+
221+
@Bean
222+
public CacheManager cm2() {
223+
return new NoOpCacheManager();
224+
}
225+
}
226+
227+
228+
@Configuration
229+
@EnableCaching(mode = AdviceMode.ASPECTJ)
230+
static class MultiCacheManagerConfigurer extends CachingConfigurerSupport {
231+
232+
@Bean
233+
public CacheManager cm1() {
234+
return new NoOpCacheManager();
235+
}
236+
237+
@Bean
238+
public CacheManager cm2() {
239+
return new NoOpCacheManager();
240+
}
241+
242+
@Override
243+
public CacheManager cacheManager() {
244+
return cm1();
245+
}
246+
247+
@Override
248+
public KeyGenerator keyGenerator() {
249+
return null;
250+
}
251+
}
252+
253+
254+
@Configuration
255+
@EnableCaching(mode = AdviceMode.ASPECTJ)
256+
static class EmptyConfigSupportConfig extends CachingConfigurerSupport {
257+
258+
@Bean
259+
public CacheManager cm() {
260+
return new NoOpCacheManager();
261+
}
262+
263+
}
264+
265+
266+
@Configuration
267+
@EnableCaching(mode = AdviceMode.ASPECTJ)
268+
static class FullCachingConfig extends CachingConfigurerSupport {
269+
270+
@Override
271+
@Bean
272+
public CacheManager cacheManager() {
273+
return new NoOpCacheManager();
274+
}
275+
276+
@Override
277+
@Bean
278+
public KeyGenerator keyGenerator() {
279+
return new SomeKeyGenerator();
280+
}
281+
282+
@Override
283+
@Bean
284+
public CacheResolver cacheResolver() {
285+
return new NamedCacheResolver(cacheManager(), "foo");
286+
}
287+
}
288+
}

0 commit comments

Comments
 (0)