spring - 如何在spring Cacheable中根据响应对象设置ttl
问题描述
我有以下缓存用例。我正在使用@Cacheable
注释,它看起来像这样:
@Cacheable(cacheNames = "sampleCache", key = "#customerId", cacheResolver = "sampleCacheResolver")
public @ResponseBody SampleResponse getSampleMethod(String customerId) {
}
TTL 设置在sampleCacheResolver
. 但是我有一个要求,我必须根据响应对象更改 TTL。例如,在响应对象中,如果说SampleResponse.month
是当前月份,我想将 ttl 设置为 1 分钟,否则我想保留默认值 3 分钟。
由于sampleCacheResolver
在请求级别被调用,我不确定如何根据响应更新 ttl。
解决方案
Spring 的 Cache Abstraction开箱即用,这是不可能的。
Spring 非常清楚,无论是 TTL(生存时间)还是 TTI(空闲超时)过期策略(甚至是驱逐策略)都不是由抽象处理的,这是有充分理由的。
Expiration 和 Eviction 实现是特定于缓存提供程序的,当条目过期或被驱逐时,许多实现可能会有不同的操作。
将 TTL 应用于响应是相当特殊的,特别是考虑到 TTL 是一个设定的时间范围。
无论如何,您有两个选择。
首先,一些缓存提供程序及其支持的 Spring 位提供了接近您所寻求的功能。
例如,我为Apache Geode开发 Spring Boot、Session 和 Data ,它可以作为Spring 的 Cache Abstraction中的缓存提供程序。
我支持的功能之一是通过基于注释的配置模型的入门级(即实体)过期策略。见这里。当然,这可以通过 Apache Geode 本身实现,因为它能够表达自定义过期策略。即使用注解实现入门级TTL是基于Apache Geode的CustomExpiry
接口。
处理条目/实体或响应 TTL 的另一种方法是覆盖/扩展 Spring 的缓存抽象。抽象中的 2 个主要接口是CacheManager
和Cache
接口。
在您的情况下,您将实现Cache
接口以包含您需要的 TTL 逻辑。您Cache
(TTL)实现将包装实际的缓存提供程序实现(例如EhCache Cache
)。然后,您必须实现CacheManager
接口来包装缓存提供程序CacheManager
实现(同样是 EhCache CacheManager
)。当框架调用您的实现时,您的实现仅用于创建包装提供者实现的CacheManager
启用 TTL 的实现的实例。本质上,您启用 TTL 的实现是使用您需要的 TTL 逻辑来增强或修饰缓存提供程序的实现。Cache
Cache
Cache
Cache
另一种可能的解决方案是使用Spring AOP。实际上,Spring 的许多特性,如缓存或事务管理(分界)都是由 Spring AOP 处理的。精心设计的 AOP Aspect 可以包装 Caching Aspect 并包含您需要的 TTL 逻辑。您必须确保 TTL AOP 方面出现在 Spring 的缓存方面之后,可以通过 bean 排序来处理。
这次我没有为您的确切用例提供示例。但是,我之前已经回答了需要“自定义”实现 SpringCache
和CacheManager
接口的问题。供您参考,您可以参考我的示例,了解如何实现自己的Cache
/CacheManager
组合。
在继续我介绍的路径之前,我鼓励您探索您的缓存提供程序,看看它是否为您提供了您所追求的 TTL 功能。您应该根据自己的需要和要求选择合适的缓存提供程序。
我知道这是很多信息,但我只是希望您有选择并从多个角度考虑问题。
推荐阅读
- windows - 将数据导入 rstudio
- swift - SwiftUI:如何播放一次乒乓动画?向前和向后播放动画的正确方法?
- r - 将多行合并为一个时间间隔
- c++ - 将对成员的引用传递给基类的构造函数
- botframework - QnA 服务主动学习是否适用于来自频道的问题?
- c++ - 试图弄清楚我需要进行哪些更改才能使此代码正常工作。使用 Visual Studio
- node.js - SCIM 补丁库
- powershell - 用不同的名称重命名多个文件
- ios - Swift - 以编程方式在 UIView 中定位项目
- r - 我的绘图没有在 RStudio 中保存或打印,我尝试了 dev.off()