如何让 Spring @Cacheable 在 AspectJ 方面工作?

Posted

技术标签:

【中文标题】如何让 Spring @Cacheable 在 AspectJ 方面工作?【英文标题】:How to make Spring @Cacheable work on top of AspectJ aspect? 【发布时间】:2016-08-19 20:54:31 【问题描述】:

我创建了一个在 Spring 应用程序中运行良好的 AspectJ 方面。现在我想添加缓存,使用 springs Cacheable 注解。

为了检查@Cacheable 是否被拾取,我使用了一个不存在的缓存管理器的名称。常规的运行时行为是抛出异常。但是在这种情况下,没有抛出异常,这表明@Cacheable 注解没有被应用到拦截对象。

/*  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;
    

鉴于我的 Aspect 已经在工作,我怎样才能让 @Cacheable 在它之上工作?

【问题讨论】:

【参考方案1】:

您可以通过使用 Spring 常规依赖注入机制并将org.springframework.cache.CacheManager 注入您的方面来实现类似的结果:

@Autowired
CacheManager cacheManager;

那么你就可以在around通知中使用缓存管理器了:

@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();
    

【讨论】:

我最终得到了类似的东西,但它并不像能够添加注释那么好,它只是工作。不过感谢您的努力。

以上是关于如何让 Spring @Cacheable 在 AspectJ 方面工作?的主要内容,如果未能解决你的问题,请参考以下文章

Spring 缓存——@Cacheable

@cacheable的缓存怎么使用

spring 中的@cacheable的key是怎么配置的

spring boot cacheable在啥情况下不生效

使用带有 @Cacheable 注释的 Spring bean 作为键

Spring中@Cacheable的用法