You need to enable JavaScript to run this app. Spring Boot如何基于返回结果实现@Cacheable条件缓存
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot如何基于返回结果实现@Cacheable条件缓存

报错原因梳理
  • 第一种写法仅判断了result属性为null的场景,未覆盖空集合的情况,完全不符合需求。
  • 第二种、第三种写法报错是由SpEL表达式解析规则导致的:
    • 直接写.size时,SpEL会默认将其作为JavaBean属性解析,寻找对应的getSize()方法,但JDK的ArrayList没有getSize()方法,只有size()实例方法,因此抛出属性不存在的异常。
    • .length是Java数组的固有属性,List属于集合框架类而非数组,自然也会抛出属性不存在的异常。
  • 额外前提:必须保证Response类中的result属性有public修饰的getResult()方法,否则SpEL无法解析到该属性,会直接报错。
  • 你给出的业务代码示例有笔误:save方法最后缺少return new Response(result);语句,否则编译不通过,无法运行。
正确配置方案

我们的需求是「仅当result属性既不为null、也不是空集合时才缓存」,对应unless的逻辑是:当result为null,或者result集合为空时,不执行缓存。
可使用以下两种可运行的写法:

  1. 调用List原生size()方法判断
@Cacheable(value = "saveCache", key = "{#a, #b, #c}", unless="#result.result == null || #result.result.size() == 0")
public Response save(String a, String b, String c) {
  // 业务逻辑块
  List<Map<String, Object>> result = new ArrayList();
  return new Response(result);
}
  1. 调用List原生isEmpty()方法判断(更简洁)
@Cacheable(value = "saveCache", key = "{#a, #b, #c}", unless="#result.result == null || #result.result.isEmpty()")
public Response save(String a, String b, String c) {
  // 业务逻辑块
  List<Map<String, Object>> result = new ArrayList();
  return new Response(result);
}

优化写法:使用SpEL安全导航操作符?.简化空判断,避免额外的null判断逻辑,等价于上面的写法:

unless="#result.result == null || #result.result?.isEmpty()"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 15:24:07