缓存抽象
自 3.1 版本起,Spring Framework 提供了对现有 Spring 应用程序透明添加缓存的支持。与事务支持类似,缓存抽象允许在代码影响最小的情况下一致地使用各种缓存解决方案。
在 Spring Framework 4.1 中,缓存抽象得到了显著扩展,支持 JSR-107 注解和更多的自定义选项。
章节摘要
📄️ 理解缓存抽象
术语“缓冲区”和“缓存”往往被交替使用。然而,请注意,它们代表不同的东西。传统上,缓冲区用作快速实体和慢速实体之间的数据中间临时存储。由于一方必须等待另一方(这会影响性能),缓冲区通过允许整个数据块一次性移动而不是小块移动来缓解这一问题。数据只在缓冲区中被写入和读取一次。此外,缓冲区对至少一个知道它的实体是可见的。
📄️ 基于声明式注解的缓存
对于缓存声明,Spring 的缓存抽象提供了一组 Java 注解:
📄️ JCache (JSR-107) 注解
从版本 4.1 开始,Spring 的缓存抽象完全支持 JCache 标准(JSR-107)注解:@CacheResult、@CachePut、@CacheRemove 和 @CacheRemoveAll 以及 @CacheDefaults、@CacheKey 和 @CacheValue 附属注解。即使不将缓存存储迁移到 JSR-107,你也可以使用这些注解。内部实现使用 Spring 的缓存抽象,并提供符合规范的默认 CacheResolver 和 KeyGenerator 实现。换句话说,如果你已经在使用 Spring 的缓存抽象,可以切换到这些标准注解,而无需更改缓存存储(或配置)。
📄️ 基于 XML 的声明式缓存
如果注解不是一个选项(可能是因为无法访问源代码或没有外部代码),你可以使用 XML 进行声明式缓存。因此,你可以在外部指定目标方法和缓存指令,而不是为方法添加缓存注解(类似于声明式事务管理建议)。上一节的示例可以转换为以下示例:
📄️ 配置缓存存储
缓存抽象提供了几种存储集成选项。要使用它们,你需要声明一个合适的 CacheManager(一个控制和管理 Cache 实例的实体,可以用来检索这些实例进行存储)。
📄️ 插入不同的后端缓存
显然,有很多缓存产品可以用作后备存储。对于那些不支持 JSR-107 的产品,你需要提供一个 CacheManager 和一个 Cache 实现。这听起来可能比实际要难,因为在实践中,这些类往往是简单的适配器,将缓存抽象框架映射到存储 API 之上,就像 Caffeine 类所做的那样。大多数 CacheManager 类可以使用 org.springframework.cache.support 包中的类(例如 AbstractCacheManager,它负责样板代码,只需完成实际的映射即可)。
📄️ 我如何设置 TTL/TTI/驱逐策略/XXX 功能?
直接通过您的缓存提供者。缓存抽象是一个抽象,而不是缓存实现。您使用的解决方案可能支持其他解决方案不支持的各种数据策略和不同的拓扑结构(例如,JDK 的 ConcurrentHashMap — 在缓存抽象中暴露它将毫无用处,因为没有后备支持)。这种功能应该直接通过后备缓存(在配置它时)或通过其本机 API 进行控制。