Skip to content

Commit

Permalink
Fix cache annotation tip
Browse files Browse the repository at this point in the history
Even if using cglib proxy mode, annotations on an interface can be recognized.

Signed-off-by: Kwangyong Kim <banana.yong@gmail.com>
  • Loading branch information
bananayong authored and jhoeller committed Dec 14, 2021
1 parent 2fb3f99 commit ceea00f
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
Expand Up @@ -73,6 +73,19 @@ public void fooServiceWithInterfaceCglib() {
fooGetSimple(service);
}

@Test
public void barServiceWithCacheableInterfaceCglib() {
this.context = new AnnotationConfigApplicationContext(BarConfigCglib.class);
BarService service = this.context.getBean(BarService.class);
Cache cache = getCache();

Object key = new Object();
assertCacheMiss(key, cache);

Object value = service.getSimple(key);
assertCacheHit(key, value, cache);
}

private void fooGetSimple(FooService service) {
Cache cache = getCache();

Expand Down Expand Up @@ -184,6 +197,31 @@ public Object getWithCondition(Object key) {
}
}

@Configuration
@Import(SharedConfig.class)
@EnableCaching(proxyTargetClass = true)
static class BarConfigCglib {

@Bean
public BarService barService() {
return new BarServiceImpl();
}
}

interface BarService {
@Cacheable(cacheNames = "testCache")
Object getSimple(Object key);
}

static class BarServiceImpl implements BarService {

private final AtomicLong counter = new AtomicLong();

@Override
public Object getSimple(Object key) {
return this.counter.getAndIncrement();
}
}

@Configuration
@Import(FooConfig.class)
Expand Down
8 changes: 3 additions & 5 deletions src/docs/asciidoc/integration.adoc
Expand Up @@ -6226,11 +6226,9 @@ if you need to annotate non-public methods, as it changes the bytecode itself.
TIP: Spring recommends that you only annotate concrete classes (and methods of concrete
classes) with the `@Cache{asterisk}` annotation, as opposed to annotating interfaces.
You certainly can place the `@Cache{asterisk}` annotation on an interface (or an interface
method), but this works only as you would expect it to if you use interface-based proxies.
The fact that Java annotations are not inherited from interfaces means that, if you use
class-based proxies (`proxy-target-class="true"`) or the weaving-based aspect
(`mode="aspectj"`), the caching settings are not recognized by the proxying and weaving
infrastructure, and the object is not wrapped in a caching proxy.
method), but this works only as you would expect it to if you use the proxy mode (`mode="proxy"`).
If you use the weaving-based aspect (`mode="aspectj"`), the caching settings are not
recognized by weaving infrastructure.

NOTE: In proxy mode (the default), only external method calls coming in through the
proxy are intercepted. This means that self-invocation (in effect, a method within the
Expand Down

0 comments on commit ceea00f

Please sign in to comment.