@Cacheable解决复杂对象形参导致的缓存失效问题(如Map参数)

在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上的记录可见被有效地缓存起来了:

### 清除使用 `@Cacheable` 注解配置的多级缓存Spring 中,当涉及到清除由 `@Cacheable` 配置的多级缓存时,可以利用 `@CacheEvict` 或者编程方式实现。对于多级缓存而言,通常会涉及多个缓存层,在这些层次结构中的每一层都可能保存有相同键的数据副本。 #### 使用 `@CacheEvict` 为了确保所有级别的缓存都能被清空,可以在更新操作上应用 `@CacheEvict` 注解,并通过设置 `allEntries=true` 来指示要移除整个命名空间内的条目: ```java @CacheEvict(value = {"levelOneCache", "levelTwoCache"}, allEntries = true) public void clearAllCaches() { // 方法体可为空或执行其他逻辑 } ``` 此方法会在调用时触发对指定名称列表中每一个缓存区域的所有条目的清理工作[^2]。 #### 编程方式清除缓存 除了注解驱动的方式外,还可以借助于 `CacheManager` 接口提供的 API 手动控制缓存的行为。下面是一个例子展示了如何获取到具体的 `Cache` 实例并对其进行清理: ```java @Autowired private CacheManager cacheManager; public void evictMultiLevelCaches(){ Collection<String> cacheNames = Arrays.asList("levelOneCache","levelTwoCache"); for (String name : cacheNames){ Cache cache = cacheManager.getCache(name); if(cache != null){ cache.clear(); } } } ``` 这种方法允许更灵活的操作,比如只针对特定条件下的某些记录进行删除而不是全部清除[^3]。 #### 结合 Layering Cache 框架 如果项目已经集成了像 Layering Cache 这样的分层缓存解决方案,则应该查阅其官方文档以获得最佳实践指导。因为不同框架可能会有不同的机制去处理跨级别的一致性和失效策略[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值