You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Redis环境下如何通过AOP运行时修改@Cacheable的condition属性?

问题分析与解决方案

你尝试通过反射修改@Cacheable注解的condition属性来关闭缓存但未生效,核心原因是Spring在应用启动阶段就完成了缓存注解的元数据解析,并将这些信息缓存起来供后续切面使用。你运行时修改的是注解代理对象的属性,并不会影响Spring已经加载好的缓存执行逻辑,所以缓存依然会正常存储数据。

正确实现思路

方案1:利用condition绑定全局开关(最简方案)

无需通过AOP反射修改注解,直接在@Cacheable的condition中引用一个全局可修改的开关变量,修改变量值即可实时控制缓存开关:

  1. 定义缓存开关配置类:
@Component
public class CacheSwitchConfig {
    // 全局缓存开关,默认开启
    private boolean cacheEnabled = true;

    public boolean isCacheEnabled() {
        return cacheEnabled;
    }

    public void setCacheEnabled(boolean cacheEnabled) {
        this.cacheEnabled = cacheEnabled;
    }
}
  1. 在@Cacheable注解中引用该开关:
@Cacheable(value = "userCache", condition = "@cacheSwitchConfig.isCacheEnabled()")
public User getUserById(Long id) {
    // 数据库查询逻辑
    return userMapper.selectById(id);
}
  1. 需要关闭缓存时,直接调用cacheSwitchConfig.setCacheEnabled(false),后续方法调用会自动跳过缓存逻辑。

方案2:通过AOP拦截缓存方法,手动跳过缓存

如果一定要用AOP实现,可以让自定义切面优先于Spring Cache切面执行,直接干预方法流程:

@Aspect
@Component
@Order(Ordered.HIGHEST_PRECEDENCE) // 确保此切面比Spring Cache切面先执行
public class CacheSwitchAspect {
    @Autowired
    private CacheSwitchConfig cacheSwitchConfig;

    @Around("@annotation(org.springframework.cache.annotation.Cacheable)")
    public Object aroundCacheableMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        // 缓存关闭时,直接执行目标方法,跳过Spring Cache逻辑
        if (!cacheSwitchConfig.isCacheEnabled()) {
            return joinPoint.proceed();
        }
        // 缓存开启时,交给Spring Cache切面处理
        return joinPoint.proceed();
    }
}

这种方式直接拦截方法执行流程,比修改注解属性更可靠,彻底绕过了Spring缓存逻辑的触发条件。

原代码失效的根本原因

Spring Cache的CacheInterceptor在初始化阶段,会将@Cacheable注解中的condition、key等属性编译成可执行表达式并缓存。后续每次方法调用时,只会执行预先编译好的表达式,不会重新读取注解的属性值。你通过反射修改的注解代理对象memberValues,并不会影响Spring已缓存的表达式逻辑,所以无法达到关闭缓存的效果。

内容的提问来源于stack exchange,提问作者Ahmed Essam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 16:25:25