I have an issue with @Cacheable
and @CacheEviction
annotations. When I call these methods in the bean where they are declared, the aop part is not getting executed.
The underlying reason for this is that the bean access to its own instance itself, instead of accessing the spring proxy.
I have read this question where it is said that in most cases it should not be necessary a bean accessing the proxy.
Probably those answers work for me. The question is:
Is there any other way to make annotated methods work? Or does it sound like I found a good reason for a bean needing to access the proxy itself?
Advertisement
Answer
As is well documented in the Spring user manual, self-invocation cannot work with Spring AOP because Spring AOP uses proxies. So if you want to make self-invocation trigger an aspect, please switch to full AspectJ via LTW (load-time weaving). It works with the original beans and does not use any proxies.
Update: If you want to avoid using native AspectJ and instead as a (pretty lame and anti-AOP) workaround want to make your component proxy-aware, of course you can use self-injection and reference the cached method using the auto-wired proxy like this:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Component; @Component public class MyComponent { @Autowired MyComponent myComponent; public void doSomething() { System.out.println(myComponent.doCacheable()); System.out.println(myComponent.doCacheable()); System.out.println(myComponent.doCacheable()); } @Cacheable("myCache") public String doCacheable() { return "" + System.nanoTime(); } }
Calling doSomething()
on the MyComponent
bean should yield output like this:
247760543178800 247760543178800 247760543178800
This proves that caching works like this. If instead you just have three lines of either System.out.println(doCacheable());
or the weird, nonsensical variant from the other (now deleted) answer
System.out.println(MyComponent.this.doCacheable());
, then you would get three different values on the console, i.e. nothing would be cached.