11.1. 缓存
Spring 框架支持透明地向应用程序添加缓存。其核心是,抽象将缓存应用于方法,从而减少基于缓存中可用信息的执行次数。缓存逻辑是透明应用的,不会对调用者造成任何干扰。只要使用@EnableCaching
注释启用缓存支持,Spring Boot 就会自动配置缓存基础设施。
检查Spring 框架参考的 相关部分以获取更多详细信息。
简而言之,要向服务的操作添加缓存,请向其方法添加相关注释,如以下示例所示:
此示例演示了如何在可能成本高昂的操作中使用缓存。在调用之前computePiDecimal
,抽象会在piDecimals
缓存中查找与参数i
匹配的条目。如果找到条目,则立即将缓存中的内容返回给调用者,并且不调用该方法。否则,将调用该方法,并在返回值之前更新缓存。
您还可以透明地使用标准 JSR-107 (JCache) 注释(例如
@CacheResult
)。但是,我们强烈建议您不要混合搭配 Spring Cache 和 JCache 注解。
如果您不添加任何特定的缓存库,Spring Boot 会自动配置一个使用内存中并发映射的简单提供程序。当需要缓存时(例如piDecimals
前面的示例),该提供程序会为您创建它。并不真正建议将简单的提供程序用于生产用途,但它非常适合入门并确保您了解其功能。当您决定要使用的缓存提供程序时,请务必阅读其文档以了解如何配置应用程序使用的缓存。几乎所有提供程序都要求您显式配置应用程序中使用的每个缓存。有些提供了一种自定义属性spring.cache.cache-names
定义的默认缓存的方法。
11.1.1. 支持的缓存提供程序
缓存抽象不提供实际的存储,而是依赖于org.springframework.cache.Cache
和org.springframework.cache.CacheManager
接口具体化的抽象。
如果您尚未定义类型CacheManager
或CacheResolver
命名的 cacheResolver
bean(请参阅 参考资料CachingConfigurer
),Spring Boot 会尝试检测以下提供程序(按指定的顺序):
JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
此外,Spring Boot for Apache Geode提供了使用 Apache Geode 作为缓存提供程序的自动配置。
如果Spring Boot 自动配置
CacheManager
,则可以通过设置spring.cache.type
属性来强制使用特定的缓存提供程序。如果您需要在某些环境(例如测试)中 使用无操作缓存,请使用此属性。使用
spring-boot-starter-cache
“Starter”快速添加基本的缓存依赖项。启动器引入了spring-context-support
。如果手动添加依赖项,则必须添加依赖项spring-context-support
才能使用 JCache 或 Caffeine 支持。
如果Spring Boot 自动配置CacheManager
,您可以在完全初始化之前通过公开实现CacheManagerCustomizer
接口的 bean 来进一步调整其配置。以下示例设置一个标志来表示null
值不应向下传递到底层映射:
在前面的示例中,需要 自动配置
ConcurrentMapCacheManager
。如果情况并非如此(您提供了自己的配置或自动配置了不同的缓存提供程序),则根本不会调用定制器。您可以拥有任意数量的定制器,也可以使用@Order
或Ordered
来进行排序。
通用的
如果上下文定义了至少一个org.springframework.cache.Cache
bean,则使用通用缓存。CacheManager
创建一个包装该类型的所有 bean。
JCache (JSR-107)
JCache通过类路径上存在的 javax.cache.spi.CachingProvider
进行引导(即,类路径上存在符合 JSR-107 的缓存库),并且由spring-boot-starter-cache
“Starter”提供JCacheCacheManager
。提供各种兼容的库,而且Spring Boot 为 Ehcache 3、Hazelcast 和 Infinispan 提供依赖管理。也可以添加任何其他兼容的库。
可能会出现多个提供者,在这种情况下必须显式指定该提供者。即使 JSR-107 标准没有强制采用标准化方法来定义配置文件的位置,Spring Boot 也会尽力通过实现细节来设置缓存,如以下示例所示:
当缓存库同时提供本机实现和 JSR-107 支持时,Spring Boot 更喜欢 JSR-107 支持,以便在切换到不同的 JSR-107 实现时可以使用相同的功能。
Spring Boot对 Hazelcast 具有普遍支持。如果单个
HazelcastInstance
可用,则它也会自动重用CacheManager
,除非指定了spring.cache.jcache.config
属性。
底层定制javax.cache.cacheManager
有两种方式:
可以通过设置
spring.cache.cache-names
属性在启动时创建缓存。如果javax.cache.configuration.Configuration
定义了自定义 bean,则它用于自定义它们。org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer
beans 通过CacheManager
的引用来调用以实现完全定制。
如果定义了 标准
javax.cache.CacheManager
bean,它会自动包装在org.springframework.cache.CacheManager
抽象期望的实现中。没有对其应用进一步的定制。
Hazelcast
Spring Boot对 Hazelcast 具有普遍支持。如果 HazelcastInstance
已自动配置并且com.hazelcast:hazelcast-spring
位于类路径上,则它会自动包装在CacheManager
.
Hazelcast 可以用作 JCache 兼容缓存或 Spring
CacheManager
兼容缓存。当设置spring.cache.type
为hazelcast
时,Spring Boot 将使用基于CacheManager
的实现。如果您想使用 Hazelcast 作为 JCache 兼容缓存,请设置spring.cache.type
为jcache
。如果您有多个符合 JCache 标准的缓存提供程序并希望强制使用 Hazelcast,则必须显式设置 JCache 提供程序。
Infinispan
Infinispan没有默认的配置文件位置,因此必须显式指定。否则,将使用默认引导程序。
可以通过设置spring.cache.cache-names
属性在启动时创建缓存。如果定义了自定义ConfigurationBuilder
bean,则它用于自定义缓存。
为了与 Spring Boot 的 Jakarta EE 9 基线兼容,必须使用 Infinispan 的-jakarta
模块。对于每个具有-jakarta
变体的模块,必须使用该变体来代替标准模块。例如,infinispan-core-jakarta
和infinispan-commons-jakarta
必须分别用来代替infinispan-core
和 infinispan-commons
。
Couchbase
如果 Spring Data Couchbase 可用并且 Couchbase 已配置,则 CouchbaseCacheManager
会自动配置。可以通过设置spring.cache.cache-names
属性在启动时创建额外的缓存,并且可以使用spring.cache.couchbase.*
属性配置缓存默认值。例如,以下配置创建cache1
并cache2
缓存条目过期时间为 10 分钟:
如果您需要对配置进行更多控制,请考虑注册CouchbaseCacheManagerBuilderCustomizer
bean。以下示例显示了为cache1
和cache2
配置特定条目到期时间的定制程序:
Redis
如果Redis可用并已配置,则会RedisCacheManager
自动配置。可以通过设置spring.cache.cache-names
属性在启动时创建额外的缓存,并且可以使用spring.cache.redis.*
属性配置缓存默认值。例如,以下配置创建cache1
并cache2
缓存生存时间为 10 分钟的内容:
默认情况下,会添加一个键前缀,这样,如果两个单独的缓存使用相同的键,Redis 不会有重叠的键,也不会返回无效值。如果您创建自己的
RedisCacheManager
.您可以通过添加自己的
RedisCacheConfiguration
@Bean
配置来完全控制默认配置。如果您需要自定义默认序列化策略,这可能很有用。
如果您需要对配置进行更多控制,请考虑注册RedisCacheManagerBuilderCustomizer
bean。以下示例显示了配置特定生存时间cache1
和 cache2
的定制程序:
Caffeine
Caffeine是 Guava 缓存的 Java 8 重写,取代了对 Guava 的支持。如果存在Caffeine,则会自动配置CaffeineCacheManager
(由“Starter”提供)。spring-boot-starter-cache
可以通过设置spring.cache.cache-names
属性在启动时创建缓存,并且可以通过以下选项之一进行自定义(按指定的顺序):
缓存规范定义为
spring.cache.caffeine.spec
定义了一个
com.github.benmanes.caffeine.cache.CaffeineSpec
bean定义了一个
com.github.benmanes.caffeine.cache.Caffeine
bean
例如,以下配置创建cache1
和cache2
缓存的最大大小为 500,生存时间为 10 分钟
如果定义了一个com.github.benmanes.caffeine.cache.CacheLoader
bean,它会自动关联到CaffeineCacheManager
. 由于CacheLoader
将会与缓存管理器管理的所有缓存相关联,因此它必须定义为CacheLoader<Object, Object>
。自动配置会忽略任何其他通用类型。
Cache2k
Cache2k是内存缓存。如果存在 Cache2k spring 集成,则会自动配置 SpringCache2kCacheManager
。
可以通过设置spring.cache.cache-names
属性在启动时创建缓存。可以使用Cache2kBuilderCustomizer
bean 自定义缓存默认值。以下示例显示了一个自定义程序,它将缓存容量配置为 200 个条目,过期时间为 5 分钟:
Simple
如果找不到其他提供程序,则配置使用 ConcurrentHashMap
作为缓存存储的简单实现。如果您的应用程序中不存在缓存库,则这是默认设置。默认情况下,会根据需要创建缓存,但您可以通过设置属性cache-names
来限制可用缓存的列表。例如,如果您只需要cache1
和cache2
缓存,请cache-names
按如下方式设置该属性:
如果您这样做并且您的应用程序使用未列出的缓存,那么它会在需要缓存时在运行时失败,但在启动时不会失败。如果您使用未声明的缓存,这类似于“真实”缓存提供程序的行为方式。
None
当您的配置中存在@EnableCaching
时,也需要合适的缓存配置。如果您有自定义CacheManager
,请考虑将其定义在单独的@Configuration
类中,以便您可以在必要时覆盖它。None 使用在测试中有用的无操作实现,切片测试默认通过@AutoConfigureCache
.
如果您需要在特定环境下使用无操作缓存而不是自动配置的缓存管理器,请将缓存类型设置为none
,如下例所示:
最后更新于