在Spring中使用 @Cacheable 注解可以非常方便地实现方法的自动缓存机制。如以下代码:
@Cacheable(value = "YwtbToken", key = "#p0")
public String createToken(String dlzh) {...}
但当@Cacheable 注解修饰的方法参数使用了复杂对象,如 Map 和 List 等集合类型、或具体的用户自定义类,那么你会发现实际上缓存是不可能生效的。
如以下方法:
@Cacheable(value = "templateQueryPage",)
public Page<LinkedHashMap<String, String>> templateQueryPage(Integer sqlNo, Map<String, String> params){...}
原因是形参 params 是一个Map,哪怕其内容跟上次调用时一致,但该对象的引用值是不同的。这就导致了无法触发缓存读取。
解决办法就是人工指定该项缓存的 key 值。在这里就要用到 SPEL (Spring表达式语言,Spring Expression Language,SpEL)了。
如以下改写后的代码:
@Cacheable(value = "templateQueryPage", key = "#sqlNo + \"-\" + #params.values().stream().collect(T(java.util.stream.Collectors).joining(\",\"))")
public Page<LinkedHashMap<String, String>> templateQueryPage(Integer sqlNo, Map<String, String> params) {...}
方法被调用后,查看Redis上的记录可见被有效地缓存起来了: