对于最新的稳定版本,请使用 Spring Framework 7.0.6!spring-doc.cadn.net.cn

理解缓存抽象

缓存与缓冲区

“缓冲区”和“缓存”这两个术语通常可以互换使用。但是请注意,它们代表的是不同的概念。传统上,缓冲区用于在快速实体和慢速实体之间作为中间的临时存储。由于一方必须等待另一方(这会影响性能),缓冲区通过允许整个数据块一次性移动而不是以小块方式移动来缓解这一问题。数据仅从缓冲区中写入和读取一次。此外,缓冲区至少对了解它的某一方是可见的。spring-doc.cadn.net.cn

另一方面,缓存根据定义是隐藏的,双方都不知道自己正在发生缓存。它也提高了性能,但它是通过以快速的方式多次读取相同的数据来实现的。spring-doc.cadn.net.cn

您可以找到关于缓冲区和缓存之间差异的进一步解释 这里spring-doc.cadn.net.cn

在核心层面,缓存抽象将缓存应用于Java方法,从而根据缓存中可用的信息减少执行次数。也就是说,每次调用目标方法时,抽象会应用缓存行为,以检查该方法是否已针对给定参数被调用过。如果已被调用,则直接返回缓存的结果,而无需调用实际的方法。如果方法尚未被调用,则会调用它,并将结果缓存并返回给用户,这样下次调用该方法时就会直接返回缓存的结果。这样,对于给定的参数集,耗时的方法(无论是CPU密集型还是IO密集型)只需调用一次,结果即可重复使用,而无需再次实际调用该方法。缓存逻辑是透明应用的,不会对调用者造成任何干扰。spring-doc.cadn.net.cn

这种方法仅适用于那些无论调用多少次,对于给定输入(或参数)都能保证返回相同输出(结果)的方法。

缓存抽象还提供了其他与缓存相关的操作,例如更新缓存内容或删除一个或所有条目。如果缓存处理的数据在应用程序运行过程中可能会发生变化,这些操作会非常有用。spring-doc.cadn.net.cn

与其他Spring框架中的服务一样,缓存服务是一种抽象(不是缓存实现),需要使用实际的存储来存储缓存数据 — 也就是说,这种抽象使你无需编写缓存逻辑,但不提供实际的数据存储。这种抽象由org.springframework.cache.Cacheorg.springframework.cache.CacheManager接口实现。spring-doc.cadn.net.cn

Spring 提供了几种实现该抽象的方式: 基于 JDK java.util.concurrent.ConcurrentMap 的缓存、Gemfire 缓存、 Caffeine 以及符合 JSR-107 标准的缓存(例如 Ehcache 3.x)。有关接入其他缓存存储和提供商的更多信息,请参见 接入不同的后端缓存spring-doc.cadn.net.cn

缓存抽象对多线程和多进程环境没有特殊处理,因为这些功能由缓存实现来处理。

如果你有一个多进程环境(即部署在多个节点上的应用程序),你需要相应地配置你的缓存提供者。根据你的使用场景,同一数据在多个节点上的副本可能已经足够。然而,如果在应用程序运行过程中修改了数据,你可能需要启用其他传播机制。spring-doc.cadn.net.cn

缓存某个特定项相当于典型的“如果未找到则继续执行并最终放入”的代码块,这在程序化缓存交互中很常见。 不会应用锁,多个线程可能会同时尝试加载相同的项。 撤出也是如此。如果多个线程同时尝试更新或撤出数据,你可能会使用过时的数据。某些缓存提供方在该方面提供了高级功能。有关更多详细信息,请参阅你的缓存提供方的文档。spring-doc.cadn.net.cn

要使用缓存抽象,你需要关注两个方面:spring-doc.cadn.net.cn