I'm working on Spring caching annotation, but i found some weird things happening in it.
Say I am calling a method in the same service class that has @CachePut annotation in it. That is not getting cached.
If i move that method to some other service implementation file and calling that method caching is working.
I need to know what i'm doing wrong.
Suppose you write the following class with @CachePut
,
public class FooBean implements Foo{
@CachePut
public String doSomething(){
}
}
Spring behind scene will create an AOP proxy that wrap your class such that it can apply some caching magic codes before or after calling the actual @CachePut
method. You can think the AOP proxy looks likes :
public class FooBeanProxy implements Foo{
private FooBean fooBean;
public String doSomething(){
//Maybe there are some caching magic codes here....
fooBean.doSomething()
//Maybe there are other caching magic codes here........
}
}
If i move that method to some other service implementation file and calling that method caching is working.
Suppose you do the following in order to call @CachePut
method:
@Component
public class App {
//FooBeanProxy actually injected HERE
@Autowired
private Foo foo;
public void startDoing(){
foo.doSomething();
}
}
What Spring injects for you is FooBeanProxy
,but not your FooBean. So, when you call that @CachePut
method , the caching magic codes will run as you are calling FooBeanProxy
Say I am calling a method in the same service class that has @CachePut annotation in it. That is not getting cached.
That means it is self-invocation . What you are invoking is this reference , which is your FooBean
instance but not that FooBeanProxy
anymore. So those caching magic will never be executed and hence the result will not be cached.
Actually ,what I talk above are already mentioned in docs. If you still want to have @CachePut
to take effect in the self-invocation case , you can use the horrible and ugly AopContext.currentProxy()
solution mentioned in the docs or use AspectJ
.