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

Spring Boot中如何基于@Cacheable注解按方法参数实现Redis缓存?

问题1:未配置key参数时如何区分不同category的缓存

@Cacheable的value属性本质是缓存分区名称,仅用来做同业务缓存的归类,并不是实际存储的缓存Key的全部内容。
Spring Cache有默认的Key生成规则,使用SimpleKeyGenerator实现:

  • 当方法没有入参时,使用SimpleKey.EMPTY作为Key
  • 当方法只有1个入参时,直接使用该入参实例作为Key
  • 当方法有多个入参时,使用包含所有入参的SimpleKey实例作为Key
    你传入的categoryA和categoryB属于不同实例,只要Category类正常重写了equals()和hashCode()方法,二者计算出来的哈希值不同,生成的缓存Key自然不同。最终存储到Redis中的Key格式为productCache::[生成的Key值],因此可以区分不同category的返回结果。

问题2:显式配置key="#category"后效果和之前一致是否正常

这是完全正常的现象,不存在配置遗漏。
因为你的方法只有一个category入参,默认的Key生成策略刚好就是用这个入参作为Key,你显式指定key="#category"的结果和默认规则完全一致,所以运行效果没有任何区别。
只有当你需要自定义Key规则时才需要额外配置key属性,例如:方法有多个入参但只需用部分参数生成Key、需要拼接固定前缀、需要取参数的某个属性(比如key="#category.id")作为Key等场景。

问题3:手动获取缓存的正确写法

你给出的写法是错误的。
cacheManager.getCache()的入参是缓存分区名称,也就是你在@Cacheable中配置的value值productCache,不需要拼接任何参数。拿到对应分区的缓存实例后,再传入Key值获取对应缓存,正确写法参考:

// 1. 获取productCache分区的缓存实例
Cache productCache = cacheManager.getCache("productCache");
if (productCache != null) {
    // 2. 传入Key(即category实例)获取缓存
    Cache.ValueWrapper wrapper = productCache.get(category);
    if (wrapper != null) {
        List<ProductDTO> cachedList = (List<ProductDTO>) wrapper.get();
    }
}

你原写法中拼接#+category的逻辑,相当于要查找名为productCache#xxx的缓存分区,这个分区不存在,自然无法拿到缓存数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 18:39:03