【问题标题】:How to set ttl based on response object in spring Cacheable如何在spring Cacheable中根据响应对象设置ttl
【发布时间】:2021-10-07 09:45:29
【问题描述】:

我有以下缓存用例。我正在使用@Cacheable 注释,它看起来像这样:

@Cacheable(cacheNames = "sampleCache", key = "#customerId", cacheResolver = "sampleCacheResolver")
public @ResponseBody SampleResponse getSampleMethod(String customerId) {
}

TTL 在sampleCacheResolver 中设置。但是我有一个要求,我必须根据响应对象更改 TTL。例如,在响应对象中,如果说SampleResponse.month 是当前月份,我想将 ttl 设置为 1 分钟,否则我想保留默认值 3 分钟。

由于 sampleCacheResolver 在请求级别被调用,我不确定如何根据响应更新 ttl。

【问题讨论】:

  • 尝试使用条件缓存,如下所示:baeldung.com/spring-cache-tutorial 可能您可以根据两个不同的条件定义两个不同的缓存。
  • @OnurBaştürk 对我来说问题是,需要根据响应来决定条件 TTL。

标签: spring spring-boot spring-cache


【解决方案1】:

这在 Spring's Cache Abstraction 开箱即用时是不可能的。

Spring 非常 clear,无论是 TTL(生存时间)还是 TTI(空闲超时)过期策略(甚至是驱逐策略)都不是由抽象处理的,这是有充分理由的。

Expiration 和 Eviction 实现是特定于缓存提供程序的,当条目过期或被驱逐时,许多实现可能会有不同的操作。

将 TTL 应用于响应是相当特殊的,特别是考虑到 TTL 是一个固定的时间范围。

无论如何,你有两个选择。

首先,一些缓存提供程序及其支持的 Spring 位提供了接近您所寻求的功能。

例如,我为 Apache Geode 处理 Spring Boot、Session 和 Data,这可以在 Spring 的缓存抽象中使用 serve as a caching provider

我支持的功能之一是通过基于注释的配置模型的入门级(即实体)过期策略。见here。当然,这可以通过 Apache Geode 本身实现,因为它能够表达自定义过期策略。即使用注解实现入门级TTL是基于Apache Geode的CustomExpiry接口。

另一种处理条目/实体或响应 TTL 的方法是覆盖/扩展 Spring 的缓存抽象。抽象中的两个主要接口是CacheManagerCache 接口。

在您的情况下,您将实现 Cache 接口以包含您需要的 TTL 逻辑。您的 Cache (TTL) 实现将包装实际的缓存提供程序实现(例如 EhCache Cache)。然后您必须实现CacheManager 接口来包装缓存提供程序CacheManager 实现(同样是EhCache CacheManager)。当框架调用时,您的 CacheManager 实现仅用于创建启用 TTL 的 Cache 实现的实例,包装提供者的 Cache 实现。本质上,您启用了 TTL 的 Cache 实现正在增强,或者 decorating 缓存提供程序的 Cache 实现具有您需要的 TTL 逻辑。

另一个可能的解决方案是使用Spring AOP。实际上,Spring 的许多特性,如缓存或事务管理(分界)都是由 Spring AOP 处理的。精心设计的 AOP Aspect 可以包装 Caching Aspect 并包含您需要的 TTL 逻辑。您必须确保 TTL AOP 方面在 Spring 的缓存方面之后,可以通过 bean 排序来处理。

这次我没有为您的确切用例提供示例。但是,我之前已经回答了需要“自定义”实现 Spring 的 CacheCacheManager 接口的问题。供您参考,您可以参考我的example,了解如何实现您自己的Cache/CacheManager 组合。

在继续我介绍的路径之前,我鼓励您探索您的缓存提供程序,看看它是否为您提供了您所追求的 TTL 功能。您应该根据自己的需要和要求选择合适的缓存提供程序。

我知道这是很多信息,但我只是希望您有选择并从多个角度考虑问题。


【讨论】:

  • 另外一点要记住,Spring 的缓存抽象的运行前提是如果Cache.get(key) 方法返回null,任何条目都不在缓存中。如果该条目最初根本不存在、被驱逐或已过期,则无关紧要。返回 null 值对于通知缓存方面下一步要执行的适当操作至关重要。
  • 感谢您提供详细信息。我将对此进行探索并尝试添加一些自定义逻辑。
猜你喜欢
  • 2019-11-01
  • 1970-01-01
  • 2018-11-30
  • 2021-11-09
  • 2013-09-03
  • 1970-01-01
  • 1970-01-01
  • 2020-07-10
  • 2013-12-27
相关资源
最近更新 更多