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

Spring Boot能否缓存方法响应而非方法执行?新手技术问询

嘿,作为Spring缓存的新手,你碰到的这个问题其实挺常见的——默认情况下Spring缓存确实是按方法维度生成缓存条目,不同方法哪怕处理的是同一个业务数据,也会因为默认Key生成规则(方法名+参数列表)产生不同的缓存Key,导致没法共享缓存。不过别担心,Spring完全支持缓存方法的响应结果,而且能轻松实现不同方法共用同一份缓存,下面给你详细拆解解决方案:

核心思路:统一缓存空间+自定义缓存Key

Spring缓存的本质是把方法的响应结果(返回值)存入指定的缓存空间,默认的Key生成逻辑会绑定方法本身,所以我们要做的就是打破这个绑定,让相同业务标识的数据用同一个缓存Key,同时让相关方法共用同一个缓存空间。

1. 针对单个方法手动指定Key

这是最直接的方式,给需要共享缓存的方法指定同一个value(缓存空间名称),然后通过key属性自定义缓存Key的生成规则。

比如你的保存方法(注意:保存/更新操作建议用@CachePut,它会执行方法后更新缓存,而@Cacheable会先查缓存再决定是否执行方法,不适合写操作):

@CachePut(value = "businessDataCache", key = "#id")
@RequestMapping("/addnew/{Id}/{IdString}/{localId}/{pid}")
public YourResponseObject addNewData(@PathVariable("Id") Long id, 
                                     @PathVariable("IdString") String idString,
                                     @PathVariable("localId") Long localId,
                                     @PathVariable("pid") Long pid) {
    // 你的保存逻辑,返回要缓存的响应对象
    return savedObject;
}

再写一个查询方法,同样指向这个缓存空间,并用相同的id作为Key:

@Cacheable(value = "businessDataCache", key = "#id")
@RequestMapping("/get/{id}")
public YourResponseObject getDataById(@PathVariable Long id) {
    // 数据库查询逻辑
    return queriedObject;
}

这样一来,只要id相同,不管是调用保存方法还是查询方法,都会命中同一条缓存条目。

2. 全局自定义Key生成器

如果你的项目里有很多方法需要统一的Key生成规则,不想每个方法都手动写key属性,可以自定义一个KeyGenerator:

@Configuration
public class CacheConfig {
    @Bean("businessKeyGenerator")
    public KeyGenerator keyGenerator() {
        return (target, method, params) -> {
            // 这里可以自定义规则,比如提取参数中的id作为唯一Key
            for (Object param : params) {
                // 假设id是Long类型的业务标识
                if (param instanceof Long) {
                    return "data_" + param.toString();
                }
            }
            // 兜底策略:如果没找到id,用默认的方法名+参数
            return method.getName() + Arrays.toString(params);
        };
    }
}

然后在方法上指定这个生成器即可:

@CachePut(value = "businessDataCache", keyGenerator = "businessKeyGenerator")
public YourResponseObject addNewData(Long id, String idString, Long localId, Long pid) { ... }

@Cacheable(value = "businessDataCache", keyGenerator = "businessKeyGenerator")
public YourResponseObject getDataById(Long id) { ... }

3. 注意事项

  • 确保你的方法返回值(要缓存的响应对象)是可序列化的,比如实现Serializable接口,否则Spring无法将对象存入缓存。
  • 区分缓存注解的使用场景:@Cacheable适合查询(先查缓存再执行方法),@CachePut适合保存/更新(执行方法后更新缓存),@CacheEvict适合删除(移除缓存条目)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:00:51