Spring框架支持透明地向应用程序添加缓存。从本质上讲,抽象将缓存应用于方法,从而根据缓存中可用的信息减少执行次数。缓存逻辑是透明应用的,不会对调用者造成任何干扰。只要通过@EnableCaching
注释启用了缓存支持,Spring Boot就会自动配置缓存基础结构。
检查Spring Framework参考的相关部分以获取更多详细信息。 | |
---|---|
简而言之,要将缓存添加到服务的操作中,请在其方法中添加相关的注释,如以下示例所示:
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@Component
public class MathService {
@Cacheable("piDecimals")
public int computePiDecimal(int i) {
// ...
}
}
本示例说明了在可能耗资巨大的操作上使用缓存的方法。在调用之前computePiDecimal
,抽象将在piDecimals
高速缓存中查找与i
参数匹配的条目。如果找到条目,则高速缓存中的内容会立即返回给调用方,并且不会调用该方法。否则,将调用该方法,并在返回值之前更新缓存。
您还可以@CacheResult 透明地使用标准JSR-107(JCache)批注(例如)。但是,我们强烈建议您不要混合使用Spring Cache和JCache批注。 |
|
---|---|
如果您不添加任何特定的缓存库,Spring Boot会自动配置一个使用内存中并发映射的简单提供程序。当需要缓存时(例如piDecimals
前面的示例),此提供程序将为您创建它。实际上,不建议将简单的提供程序用于生产用途,但是它对于入门并确保您了解功能非常有用。确定要使用的缓存提供程序后,请确保阅读其文档,以了解如何配置应用程序使用的缓存。几乎所有提供程序都要求您显式配置在应用程序中使用的每个缓存。一些提供了一种自定义spring.cache.cache-names
属性定义的默认缓存的方法。
也可以透明地更新或从缓存中逐出数据。 | |
---|---|
13.1 支持的缓存提供程序
缓存抽象不提供实际的存储,而是依赖于org.springframework.cache.Cache
和org.springframework.cache.CacheManager
接口实现的抽象。
如果尚未定义类型CacheManager
或CacheResolver
名称的bean cacheResolver
(请参阅参考资料CachingConfigurer
),Spring Boot会尝试检测以下提供程序(按指示的顺序):
- 泛型
- JCache(JSR-107)(EhCache 3,Hazelcast,Infinispan等)
- EhCache 2.x
- 淡褐色
- Infinispan
- Couchbase
- 雷迪斯
- 咖啡因
- 简单
| | 也可以通过设置属性来强制特定的缓存提供程序
spring.cache.type
。如果您需要在某些环境(例如测试)中完全禁用缓存,请使用此属性。 | | :—-: | —- |
使用spring-boot-starter-cache “入门”可以快速添加基本缓存依赖项。起动器带进来spring-context-support 。如果您手动添加依赖项,则必须包括spring-context-support 才能使用JCache,EhCache 2.x或Caffeine支持。 |
|
---|---|
如果CacheManager
Spring Boot自动配置了,您可以通过公开实现该CacheManagerCustomizer
接口的bean,在完全初始化之前进一步调整其配置。下面的示例设置一个标志,指示null
应将值向下传递到基础映射:
@Bean
public CacheManagerCustomizer<ConcurrentMapCacheManager> cacheManagerCustomizer() {
return new CacheManagerCustomizer<ConcurrentMapCacheManager>() {
@Override
public void customize(ConcurrentMapCacheManager cacheManager) {
cacheManager.setAllowNullValues(false);
}
};
}
在前面的示例中,需要进行自动配置ConcurrentMapCacheManager 。如果不是这种情况(您提供了自己的配置,或者自动配置了其他缓存提供程序),则根本不会调用定制程序。您可以根据需要拥有任意数量的定制程序,也可以使用@Order 或对其进行排序Ordered 。 |
|
---|---|
13.1.1 泛型
如果上下文定义了至少一个org.springframework.cache.Cache
bean,则使用通用缓存。将CacheManager
包装该类型的所有bean。
13.1.2 JCache(JSR-107)
JCache通过javax.cache.spi.CachingProvider
类路径上的存在进行引导(即,类路径上存在符合JSR-107的缓存库),并且JCacheCacheManager
由spring-boot-starter-cache
“启动器”提供。提供了各种兼容的库,Spring Boot为Ehcache 3,Hazelcast和Infinispan提供了依赖管理。也可以添加任何其他兼容的库。
可能会出现多个提供者,在这种情况下,必须明确指定提供者。即使JSR-107标准没有强制采用标准化的方式来定义配置文件的位置,Spring Boot也会尽其最大努力来容纳具有实现细节的缓存,如以下示例所示:
物产
Yaml
# Only necessary if more than one provider is present
spring.cache.jcache.provider=com.acme.MyCachingProvider
spring.cache.jcache.config=classpath:acme.xml
当缓存库同时提供本机实现和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
使用的引用调用beanCacheManager
进行完全定制。 | | 如果javax.cache.CacheManager
定义了标准bean,则它将自动包装在org.springframework.cache.CacheManager
抽象期望的实现中。不再对其应用定制。 | | :—-: | —- |
13.1.3 EhCache 2.x
如果ehcache.xml
可以在类路径的根目录找到名为的文件,则使用EhCache2.x。如果找到EhCache 2.x,则使用“启动器”EhCacheCacheManager
提供的spring-boot-starter-cache
启动程序引导缓存管理器。也可以提供备用配置文件,如以下示例所示:
物产
Yaml
spring.cache.ehcache.config=classpath:config/another-config.xml
13.1.4 淡褐色
Spring Boot对Hazelcast具有常规支持。如果HazelcastInstance
已经自动配置了,则会自动将其包装在中CacheManager
。
13.1.5 Infinispan
Infinispan没有默认配置文件位置,因此必须明确指定它。否则,将使用默认的引导程序。
物产
Yaml
spring.cache.infinispan.config=infinispan.xml
可以在启动时通过设置spring.cache.cache-names
属性来创建缓存。如果定义了定制ConfigurationBuilder
bean,则将其用于定制高速缓存。
Spring Boot对Infinispan的支持仅限于嵌入式模式,并且非常基础。如果您需要更多选择,则应该使用官方的Infinispan Spring Boot启动程序。有关更多详细信息,请参见Infinispan的文档。 | |
---|---|
13.1.6 Couchbase
如果Spring Data Couchbase可用并且已配置Couchbase ,CouchbaseCacheManager
则会自动配置a。可以通过设置spring.cache.cache-names
属性在启动时创建其他缓存,并且可以使用spring.cache.couchbase.*
属性配置缓存默认值。例如,以下配置创建cache1
和cache2
缓存条目的到期时间为10分钟:
物产
Yaml
spring.cache.cache-names=cache1,cache2
spring.cache.couchbase.expiration=10m
如果需要对配置进行更多控制,请考虑注册CouchbaseCacheManagerBuilderCustomizer
Bean。以下示例显示了一个定制程序,它为cache1
和配置特定的条目到期时间cache2
:
@Bean
public CouchbaseCacheManagerBuilderCustomizer myCouchbaseCacheManagerBuilderCustomizer() {
return (builder) -> builder
.withCacheConfiguration("cache1",
CouchbaseCacheConfiguration.defaultCacheConfig().entryExpiry(Duration.ofSeconds(10)))
.withCacheConfiguration("cache2",
CouchbaseCacheConfiguration.defaultCacheConfig().entryExpiry(Duration.ofMinutes(1)));
}
13.1.7 Redis
如果Redis可用并已配置,RedisCacheManager
则会自动配置a。可以通过设置spring.cache.cache-names
属性在启动时创建其他缓存,并且可以使用spring.cache.redis.*
属性配置缓存默认值。例如,以下配置创建cache1
和cache2
缓存的_生存时间为_10分钟:
物产
Yaml
spring.cache.cache-names=cache1,cache2
spring.cache.redis.time-to-live=10m
默认情况下,会添加密钥前缀,这样,如果两个单独的缓存使用相同的密钥,则Redis不会有重叠的密钥,也不会返回无效值。如果您创建自己的,我们强烈建议将此设置保持启用状态RedisCacheManager 。 |
|
---|---|
您可以通过添加RedisCacheConfiguration @Bean 自己的a来完全控制默认配置。如果您要自定义默认的序列化策略,这将很有用。 |
|
---|---|
如果需要对配置进行更多控制,请考虑注册RedisCacheManagerBuilderCustomizer
Bean。以下示例显示了一个定制程序,它为cache1
and配置生存时间cache2
。
@Bean
public RedisCacheManagerBuilderCustomizer myRedisCacheManagerBuilderCustomizer() {
return (builder) -> builder
.withCacheConfiguration("cache1",
RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(10)))
.withCacheConfiguration("cache2",
RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(1)));
}
13.1.8 Caffeine
Caffeine是对Guava缓存的Java 8重写,取代了对Guava的支持。如果存在咖啡因,CaffeineCacheManager
则将spring-boot-starter-cache
自动配置(由“入门”提供)。缓存可以在启动时通过设置spring.cache.cache-names
属性来创建,并且可以通过以下方式之一(按指示的顺序)进行自定义:
- 缓存规范由
spring.cache.caffeine.spec
com.github.benmanes.caffeine.cache.CaffeineSpec
定义了一个beancom.github.benmanes.caffeine.cache.Caffeine
定义了一个bean
例如,以下配置创建cache1
和cache2
缓存的最大大小为500,_生存时间为_10分钟
物产
Yaml
spring.cache.cache-names=cache1,cache2
spring.cache.caffeine.spec=maximumSize=500,expireAfterAccess=600s
如果com.github.benmanes.caffeine.cache.CacheLoader
定义了bean,它将自动与关联CaffeineCacheManager
。由于CacheLoader
将会与缓存管理器管理的所有缓存相关联,因此必须将其定义为CacheLoader<Object, Object>
。自动配置将忽略任何其他通用类型。
13.1.9 简单
如果找不到其他提供者,ConcurrentHashMap
则配置使用作为缓存存储的简单实现。如果您的应用程序中没有缓存库,则这是默认设置。默认情况下,将根据需要创建缓存,但是您可以通过设置cache-names
属性来限制可用缓存的列表。例如,如果只需要cache1
和cache2
缓存,则按cache-names
如下所示设置属性:
物产
Yaml
spring.cache.cache-names=cache1,cache2
如果这样做,并且您的应用程序使用未列出的缓存,则需要缓存时,它将在运行时失败,但不会在启动时失败。这类似于使用未声明的缓存时“实际”缓存提供程序的行为。
13.1.10 没有
当@EnableCaching
配置中存在时,也将期望使用合适的缓存配置。如果需要在某些环境中完全禁用缓存,请强制缓存类型none
使用无操作实现,如以下示例所示:
物产
Yaml
spring.cache.type=none