You need to enable JavaScript to run this app. Spring @Cacheable使用keyGenerator时unless调用静态方法不生效报错
优惠活动
大模型
产品
解决方案
定价
更多

Spring @Cacheable使用keyGenerator时unless调用静态方法不生效报错

核心报错根因
  • 最直接的触发原因是SpEL表达式冗余包裹了#{}结构
    Spring缓存注解(@Cacheable、@CacheEvict等)中所有支持SpEL解析的属性(包括key、condition、unless),框架会默认将属性值直接作为SpEL表达式做解析处理,不需要额外嵌套#{}结构。如果额外包裹#{},SpEL解析器会将整段内容识别为普通文本字面值,完全不触发内部的静态方法调用逻辑,最终抛出静态方法不存在的报错。
  • 常见的连带配置错误
    • 静态方法的全限定类名拼写错误:如果类名、包名存在大小写偏差、少写包层级,即使SpEL解析正常,也会抛出方法找不到的异常
    • 参数引用错位:表达式中使用#p0指代第一个入参(query对象)的写法本身符合Spring缓存的SpEL规则,不需要依赖编译期的-parameters参数;但如果方法存在多个重载、AOP代理切面被其他逻辑干扰,可能会出现参数索引偏移,可临时替换为打印参数值的SpEL做校验
修复方案
  • 移除unless属性值外层的冗余#{}包裹,调整为如下写法:
    @Cacheable(
        value = CURRENCY_CHANNELS_CACHE,
        keyGenerator = CURRENCY_CHANNEL_CACHE_KEY_GENERATOR,
        unless = "T(com.cache.MyCacheKeyGenerator).isQueryNotCacheable(#p0)"
    )
    public List<Item> getQueryForCollection(final QueryBuilder query, final String sort)
    
  • 校验com.cache.MyCacheKeyGenerator类的静态方法修饰符:确保方法是public static、返回值为boolean类型,没有被访问权限限制
  • 验证生效逻辑:在静态判断方法中增加日志打印,触发业务方法调用,观察是否能正常进入方法执行逻辑

注意:unless表达式的执行时机为「缓存键生成完成、目标业务方法执行结束之后」,当表达式返回true时,业务方法的执行结果不会被写入缓存;如果需要在业务方法执行前就判断是否跳过缓存,需要将判断逻辑配置在condition属性中。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.24 05:54:02