Spring Boot Quiz: @Cacheable with Proxy Calls
When calling findByIdWithFallback(), is the result cached?
A) Yes, always cached
B) No, caching is bypassed
C) Only on first call
D) Depends on cache configuration
Answer
Answer is B) No, caching is bypassed
In Spring @Cacheable annotation, like other Spring AOP (Aspect-oriented programming) annotations such as `@Transactional`, is implemented using proxying.
When the spring application context starts, it creates a proxy object around the original UserService bean.
When a method is annotated with
@Cacheable(likefindById) is called externally on theUserServicebean, the call goes through this proxy.The proxy intercepts the call, executes the caching logic (checking the cache, and if missed, calling the original method and storing the result), and then forwards the call to the original bean’s method if necessary.
In the scenario provided above:
A call is made to
findByIdWithFallback(id). This call is made on the proxy ofUserService.The
findByIdWithFallbackmethod itself does not have the@Cacheableannotation, so the proxy simply calls the original method implementation on the targetUserServicebean.Inside the
UserServicebean, thefindByIdWithFallbackmethod performs an internal call tofindById(id)using thethisreference:return findById(id);.This internal call bypasses the proxy. Since the call is not routed through the proxy, the Spring AOP interceptor responsible for the
@Cacheablelogic is never executed.Therefore, the
findByIdmethod’s caching is bypassed when called internally from another method within the same object (findByIdWithFallback).
How can we fix this?
Injecting the Proxy (Self-Injection):
To ensure the caching logic is applied to the findById method even from the findByIdWithFallback method, we must route the internal call through the proxy.
Add @Cacheable on findByIdWithFallback method:
External Call to
findByIdWithFallback(id)is intercepted by the proxy. Proxy checks the cache for findByIdWithFallback(id).
Cache Hit: The cached result for findByIdWithFallback is returned.
The original method is skipped.
Cache Miss: The original findByIdWithFallback The method is executed.
This method then internally calls this.findById(id).



