Skip to content

Commit 3564616

Browse files
snicolljhoeller
authored andcommitted
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 (cherry picked from commit 6cd85dd)
1 parent 07c9c55 commit 3564616

File tree

6 files changed

+395
-12
lines changed

6 files changed

+395
-12
lines changed

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

Lines changed: 11 additions & 4 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.
@@ -24,10 +24,11 @@
2424
import org.springframework.context.annotation.Role;
2525

2626
/**
27-
* {@code @Configuration} class that registers the Spring infrastructure beans necessary
28-
* to enable AspectJ-based annotation-driven cache management.
27+
* {@code @Configuration} class that registers the Spring infrastructure beans
28+
* necessary to enable AspectJ-based annotation-driven cache management.
2929
*
3030
* @author Chris Beams
31+
* @author Stephane Nicoll
3132
* @since 3.1
3233
* @see org.springframework.cache.annotation.EnableCaching
3334
* @see org.springframework.cache.annotation.CachingConfigurationSelector
@@ -39,12 +40,18 @@ public class AspectJCachingConfiguration extends AbstractCachingConfiguration {
3940
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
4041
public AnnotationCacheAspect cacheAspect() {
4142
AnnotationCacheAspect cacheAspect = AnnotationCacheAspect.aspectOf();
42-
if (this.cacheManager != null) {
43+
if (this.cacheResolver != null) {
44+
cacheAspect.setCacheResolver(this.cacheResolver);
45+
}
46+
else if (this.cacheManager != null) {
4347
cacheAspect.setCacheManager(this.cacheManager);
4448
}
4549
if (this.keyGenerator != null) {
4650
cacheAspect.setKeyGenerator(this.keyGenerator);
4751
}
52+
if (this.errorHandler != null) {
53+
cacheAspect.setErrorHandler(this.errorHandler);
54+
}
4855
return cacheAspect;
4956
}
5057

Lines changed: 285 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
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.CacheResolver;
35+
import org.springframework.cache.interceptor.KeyGenerator;
36+
import org.springframework.cache.interceptor.NamedCacheResolver;
37+
import org.springframework.cache.interceptor.SimpleCacheErrorHandler;
38+
import org.springframework.cache.interceptor.SimpleCacheResolver;
39+
import org.springframework.cache.support.NoOpCacheManager;
40+
import org.springframework.context.ConfigurableApplicationContext;
41+
import org.springframework.context.annotation.AdviceMode;
42+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
43+
import org.springframework.context.annotation.Bean;
44+
import org.springframework.context.annotation.Configuration;
45+
46+
import static org.junit.Assert.*;
47+
48+
/**
49+
* @author Stephane Nicoll
50+
*/
51+
public class AspectJEnableCachingIsolatedTests {
52+
53+
private ConfigurableApplicationContext ctx;
54+
55+
56+
private void load(Class<?>... config) {
57+
this.ctx = new AnnotationConfigApplicationContext(config);
58+
}
59+
60+
@After
61+
public void closeContext() {
62+
if (this.ctx != null) {
63+
this.ctx.close();
64+
}
65+
}
66+
67+
68+
@Test
69+
public void testKeyStrategy() {
70+
load(EnableCachingConfig.class);
71+
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
72+
assertSame(this.ctx.getBean("keyGenerator", KeyGenerator.class), aspect.getKeyGenerator());
73+
}
74+
75+
@Test
76+
public void testCacheErrorHandler() {
77+
load(EnableCachingConfig.class);
78+
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
79+
assertSame(this.ctx.getBean("errorHandler", CacheErrorHandler.class), aspect.getErrorHandler());
80+
}
81+
82+
83+
// --- local tests -------
84+
85+
@Test
86+
public void singleCacheManagerBean() {
87+
load(SingleCacheManagerConfig.class);
88+
}
89+
90+
@Test
91+
public void multipleCacheManagerBeans() {
92+
try {
93+
load(MultiCacheManagerConfig.class);
94+
}
95+
catch (IllegalStateException ex) {
96+
assertTrue(ex.getMessage().contains("bean of type CacheManager"));
97+
}
98+
}
99+
100+
@Test
101+
public void multipleCacheManagerBeans_implementsCachingConfigurer() {
102+
load(MultiCacheManagerConfigurer.class); // does not throw
103+
}
104+
105+
@Test
106+
public void multipleCachingConfigurers() {
107+
try {
108+
load(MultiCacheManagerConfigurer.class, EnableCachingConfig.class);
109+
}
110+
catch (BeanCreationException ex) {
111+
Throwable root = ex.getRootCause();
112+
assertTrue(root instanceof IllegalStateException);
113+
assertTrue(ex.getMessage().contains("implementations of CachingConfigurer"));
114+
}
115+
}
116+
117+
@Test
118+
public void noCacheManagerBeans() {
119+
try {
120+
load(EmptyConfig.class);
121+
}
122+
catch (IllegalStateException ex) {
123+
assertTrue(ex.getMessage().contains("No bean of type CacheManager"));
124+
}
125+
}
126+
127+
@Test
128+
@Ignore("AspectJ has some sort of caching that makes this one fail")
129+
public void emptyConfigSupport() {
130+
load(EmptyConfigSupportConfig.class);
131+
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
132+
assertNotNull(aspect.getCacheResolver());
133+
assertEquals(SimpleCacheResolver.class, aspect.getCacheResolver().getClass());
134+
assertSame(this.ctx.getBean(CacheManager.class),
135+
((SimpleCacheResolver) aspect.getCacheResolver()).getCacheManager());
136+
}
137+
138+
@Test
139+
public void bothSetOnlyResolverIsUsed() {
140+
load(FullCachingConfig.class);
141+
142+
AnnotationCacheAspect aspect = this.ctx.getBean(AnnotationCacheAspect.class);
143+
assertSame(this.ctx.getBean("cacheResolver"), aspect.getCacheResolver());
144+
assertSame(this.ctx.getBean("keyGenerator"), aspect.getKeyGenerator());
145+
}
146+
147+
148+
@Configuration
149+
@EnableCaching(mode = AdviceMode.ASPECTJ)
150+
static class EnableCachingConfig extends CachingConfigurerSupport {
151+
152+
@Override
153+
@Bean
154+
public CacheManager cacheManager() {
155+
return CacheTestUtils.createSimpleCacheManager("testCache", "primary", "secondary");
156+
}
157+
158+
@Bean
159+
public CacheableService<?> service() {
160+
return new DefaultCacheableService();
161+
}
162+
163+
@Bean
164+
public CacheableService<?> classService() {
165+
return new AnnotatedClassCacheableService();
166+
}
167+
168+
@Override
169+
@Bean
170+
public KeyGenerator keyGenerator() {
171+
return new SomeKeyGenerator();
172+
}
173+
174+
@Override
175+
@Bean
176+
public CacheErrorHandler errorHandler() {
177+
return new SimpleCacheErrorHandler();
178+
}
179+
180+
@Bean
181+
public KeyGenerator customKeyGenerator() {
182+
return new SomeCustomKeyGenerator();
183+
}
184+
185+
@Bean
186+
public CacheManager customCacheManager() {
187+
return CacheTestUtils.createSimpleCacheManager("testCache");
188+
}
189+
}
190+
191+
192+
@Configuration
193+
@EnableCaching(mode = AdviceMode.ASPECTJ)
194+
static class EmptyConfig {
195+
}
196+
197+
198+
@Configuration
199+
@EnableCaching(mode = AdviceMode.ASPECTJ)
200+
static class SingleCacheManagerConfig {
201+
202+
@Bean
203+
public CacheManager cm1() {
204+
return new NoOpCacheManager();
205+
}
206+
}
207+
208+
209+
@Configuration
210+
@EnableCaching(mode = AdviceMode.ASPECTJ)
211+
static class MultiCacheManagerConfig {
212+
213+
@Bean
214+
public CacheManager cm1() {
215+
return new NoOpCacheManager();
216+
}
217+
218+
@Bean
219+
public CacheManager cm2() {
220+
return new NoOpCacheManager();
221+
}
222+
}
223+
224+
225+
@Configuration
226+
@EnableCaching(mode = AdviceMode.ASPECTJ)
227+
static class MultiCacheManagerConfigurer extends CachingConfigurerSupport {
228+
229+
@Bean
230+
public CacheManager cm1() {
231+
return new NoOpCacheManager();
232+
}
233+
234+
@Bean
235+
public CacheManager cm2() {
236+
return new NoOpCacheManager();
237+
}
238+
239+
@Override
240+
public CacheManager cacheManager() {
241+
return cm1();
242+
}
243+
244+
@Override
245+
public KeyGenerator keyGenerator() {
246+
return null;
247+
}
248+
}
249+
250+
251+
@Configuration
252+
@EnableCaching(mode = AdviceMode.ASPECTJ)
253+
static class EmptyConfigSupportConfig extends CachingConfigurerSupport {
254+
255+
@Bean
256+
public CacheManager cm() {
257+
return new NoOpCacheManager();
258+
}
259+
260+
}
261+
262+
263+
@Configuration
264+
@EnableCaching(mode = AdviceMode.ASPECTJ)
265+
static class FullCachingConfig extends CachingConfigurerSupport {
266+
267+
@Override
268+
@Bean
269+
public CacheManager cacheManager() {
270+
return new NoOpCacheManager();
271+
}
272+
273+
@Override
274+
@Bean
275+
public KeyGenerator keyGenerator() {
276+
return new SomeKeyGenerator();
277+
}
278+
279+
@Override
280+
@Bean
281+
public CacheResolver cacheResolver() {
282+
return new NamedCacheResolver(cacheManager(), "foo");
283+
}
284+
}
285+
}

0 commit comments

Comments
 (0)