I created an AspectJ aspect which runs fine within a spring application. Now I want to add caching, using springs Cacheable annotation.
To check that @Cacheable gets picked up, I'm using the name of a non-existing cache manager. The regular run-time behavior is that an exception is thrown. But in this case, no exception is being thrown, which suggests that the @Cacheable annotation isn't being applied to the intercepting object.
/* { package, some more imports... } */
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.cache.annotation.Cacheable;
@Aspect
public class GetPropertyInterceptor
{
@Around( "call(* *.getProperty(..))" )
@Cacheable( cacheManager = "nonExistingCacheManager", value = "thisShouldBlowUp", key = "#nosuchkey" )
public Object intercepting( ProceedingJoinPoint pjp ) throws Throwable
{
Object o;
/* { modify o } */
return o;
}
}
Given that my Aspect is working already, how can I make @Cacheable work on top of it?
You can achieve similar results, by using Spring regular dependency injection mechanism and inject a org.springframework.cache.CacheManager
into your aspect:
@Autowired
CacheManager cacheManager;
Then you can use the cache manager in the around advice:
@Around( "call(* *.getProperty(..))" )
public Object intercepting( ProceedingJoinPoint pjp ) throws Throwable
{
Cache cache = cacheManager.getCache("aopCache");
String key = "whatEverKeyYouGenerateFromPjp";
Cache.ValueWrapper valueWrapper = cache.get(key);
if (valueWrapper == null) {
Object o;
/* { modify o } */
cache.put(key, o);
return o;
}
else {
return valueWrapper.get();
}
}
来源:https://stackoverflow.com/questions/39047520/how-to-make-spring-cacheable-work-on-top-of-aspectj-aspect