Caching
Spring Framework 提供对透明地将缓存添加到应用程序的支持。在它的核心,这个抽象对方法应用了缓存,因此基于缓存中可用信息减少执行次数。缓存逻辑以透明的方式应用,没有任何对调用者的干扰。只要使用 @EnableCaching
注解启用缓存支持,Spring Boot 就能自动配置缓存基础设施。
The Spring Framework provides support for transparently adding caching to an application.
At its core, the abstraction applies caching to methods, thus reducing the number of executions based on the information available in the cache.
The caching logic is applied transparently, without any interference to the invoker.
Spring Boot auto-configures the cache infrastructure as long as caching support is enabled by using the @EnableCaching
annotation.
有关更多详细信息,请查阅 Spring Framework 参考的 {url-spring-framework-docs}/integration/cache.html[相关部分]。 |
Check the {url-spring-framework-docs}/integration/cache.html[relevant section] of the Spring Framework reference for more details. |
简而言之,若要向服务的某个操作添加缓存,请对其方法添加相关注释,如下例所示:
In a nutshell, to add caching to an operation of your service add the relevant annotation to its method, as shown in the following example: include-code::MyMathService[]
本示例说明了在潜在成本高昂的操作上使用缓存的方法。在调用 computePiDecimal
之前,抽象将查找 piDecimals
缓存中与 i
参数匹配的条目。如果找到条目,缓存中的内容将立即返回给调用者,且该方法不会被调用。否则,将调用该方法,且在返回该值之前先对缓存进行更新。
This example demonstrates the use of caching on a potentially costly operation.
Before invoking computePiDecimal
, the abstraction looks for an entry in the piDecimals
cache that matches the i
argument.
If an entry is found, the content in the cache is immediately returned to the caller, and the method is not invoked.
Otherwise, the method is invoked, and the cache is updated before returning the value.
你也可以透明地使用标准的 JSR-107(JCache)注解(例如 @CacheResult
)。但是,我们强烈建议你不要混合使用 Spring Cache 和 JCache 注解。
You can also use the standard JSR-107 (JCache) annotations (such as @CacheResult
) transparently.
However, we strongly advise you to not mix and match the Spring Cache and JCache annotations.
如果你没有添加任何特定的缓存库,Spring Boot 会自动配置一个使用内存中的并发映射的 simple provider。当需要使用缓存时(例如在前面的示例中的 piDecimals
),此提供程序会为你创建缓存。简单的提供程序并不适合用于生产用途,但是非常适合于入门和确保你了解这些特性。当你决定要使用的缓存提供程序时,请务必仔细阅读其文档以了解如何配置你的应用程序使用的缓存。几乎所有提供程序都要求你明确配置应用程序中使用的每个缓存。有些提供程序提供自定义由 configprop:spring.cache.cache-names[] 属性定义的默认缓存的方法。
If you do not add any specific cache library, Spring Boot auto-configures a simple provider that uses concurrent maps in memory.
When a cache is required (such as piDecimals
in the preceding example), this provider creates it for you.
The simple provider is not really recommended for production usage, but it is great for getting started and making sure that you understand the features.
When you have made up your mind about the cache provider to use, please make sure to read its documentation to figure out how to configure the caches that your application uses.
Nearly all providers require you to explicitly configure every cache that you use in the application.
Some offer a way to customize the default caches defined by the configprop:spring.cache.cache-names[] property.
还可以透明地将数据从缓存中 {url-spring-framework-docs}/integration/cache/annotations.html#cache-annotations-put[更新] 或 {url-spring-framework-docs}/integration/cache/annotations.html#cache-annotations-evict[逐出]。 |
It is also possible to transparently {url-spring-framework-docs}/integration/cache/annotations.html#cache-annotations-put[update] or {url-spring-framework-docs}/integration/cache/annotations.html#cache-annotations-evict[evict] data from the cache. |
Supported Cache Providers
缓存抽象不提供实际的存储,它依赖 org.springframework.cache.Cache
和 org.springframework.cache.CacheManager
接口实现的抽象。
The cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache
and org.springframework.cache.CacheManager
interfaces.
如果你尚未定义 CacheManager
类型的 Bean 或名为 cacheResolver
的 CacheResolver
(请参见 {url-spring-framework-javadoc}/org/springframework/cache/annotation/CachingConfigurer.html[CachingConfigurer
]),Spring Boot 将尝试按指示的顺序检测以下提供程序。
If you have not defined a bean of type CacheManager
or a CacheResolver
named cacheResolver
(see {url-spring-framework-javadoc}/org/springframework/cache/annotation/CachingConfigurer.html[CachingConfigurer
]), Spring Boot tries to detect the following providers (in the indicated order):
-
JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
此外,{url-spring-boot-for-apache-geode-site}[Spring Boot for Apache Geode] 提供 {url-spring-boot-for-apache-geode-docs}#geode-caching-provider[用于将 Apache Geode 用作缓存提供程序的自动配置]。
Additionally, {url-spring-boot-for-apache-geode-site}[Spring Boot for Apache Geode] provides {url-spring-boot-for-apache-geode-docs}#geode-caching-provider[auto-configuration for using Apache Geode as a cache provider].
如果 Spring Boot 自动配置 |
If the |
使用 |
Use the |
如果 Spring Boot 自动配置 CacheManager
,则可以在完全初始化之前通过公开一个实现了 CacheManagerCustomizer
接口的 Bean 来进一步调整其配置。以下示例设置一个标记来说 null
值不应传递到底层映射:
If the CacheManager
is auto-configured by Spring Boot, you can further tune its configuration before it is fully initialized by exposing a bean that implements the CacheManagerCustomizer
interface.
The following example sets a flag to say that null
values should not be passed down to the underlying map:
在前面的示例中,会预期自动配置 |
In the preceding example, an auto-configured |
Generic
如果上下文定义 at least 个 org.springframework.cache.Cache
Bean,则使用通用缓存。将创建包含该类型的所有 Bean 的 CacheManager
。
Generic caching is used if the context defines at least one org.springframework.cache.Cache
bean.
A CacheManager
wrapping all beans of that type is created.
JCache (JSR-107)
通过类路径中存在 javax.cache.spi.CachingProvider
对 JCache 进行引导(也就是说,类路径中存在 JSR-107 兼容缓存库),而 JCacheCacheManager
由 spring-boot-starter-cache
“Starter” 提供。现有多种兼容库可用,Spring Boot 为 Ehcache 3、Hazelcast 和 Infinispan 提供依赖项管理。也可以添加任何其他兼容库。
JCache is bootstrapped through the presence of a javax.cache.spi.CachingProvider
on the classpath (that is, a JSR-107 compliant caching library exists on the classpath), and the JCacheCacheManager
is provided by the spring-boot-starter-cache
“Starter”.
Various compliant libraries are available, and Spring Boot provides dependency management for Ehcache 3, Hazelcast, and Infinispan.
Any other compliant library can be added as well.
可能有多个提供者,在这种情况下必须明确指定提供者。即使 JSR-107 标准没有强制执行定义配置文件位置的标准化方式,Spring Boot 也会尽力容纳带有实现细节的缓存设置,如下例所示:
It might happen that more than one provider is present, in which case the provider must be explicitly specified. Even if the JSR-107 standard does not enforce a standardized way to define the location of the configuration file, Spring Boot does its best to accommodate setting a cache with implementation details, as shown in the following example:
# Only necessary if more than one provider is present spring: cache: jcache: provider: "com.example.MyCachingProvider" config: "classpath:example.xml"
当缓存库既提供本机实现又支持 JSR-107 时,Spring Boot 更喜欢使用 JSR-107 支持,以便在你切换到不同的 JSR-107 实现时可以使用相同的特性。 |
When a cache library offers both a native implementation and JSR-107 support, Spring Boot prefers the JSR-107 support, so that the same features are available if you switch to a different JSR-107 implementation. |
Spring Boot 拥有 general support for Hazelcast。如果一个 |
Spring Boot has general support for Hazelcast.
If a single |
有两种方法可以自定义基础 javax.cache.cacheManager
:
There are two ways to customize the underlying javax.cache.cacheManager
:
-
Caches can be created on startup by setting the configprop:spring.cache.cache-names[] property. If a custom
javax.cache.configuration.Configuration
bean is defined, it is used to customize them. -
org.springframework.boot.autoconfigure.cache.JCacheManagerCustomizer
beans are invoked with the reference of theCacheManager
for full customization.
如果定义了标准 |
If a standard |
Hazelcast
Spring Boot 拥有 general support for Hazelcast。如果已自动配置 HazelcastInstance
且 com.hazelcast:hazelcast-spring
在类路径上,则自动将其包装在 CacheManager
中。
Spring Boot has general support for Hazelcast.
If a HazelcastInstance
has been auto-configured and com.hazelcast:hazelcast-spring
is on the classpath, it is automatically wrapped in a CacheManager
.
Hazelcast 可用作 JCache 兼容缓存或 Spring |
Hazelcast can be used as a JCache compliant cache or as a Spring |
Infinispan
Infinispan 没有默认配置文件位置,因此必须明确指定。否则,将使用默认引导程序。
Infinispan has no default configuration file location, so it must be specified explicitly. Otherwise, the default bootstrap is used.
spring: cache: infinispan: config: "infinispan.xml"
可以通过设置 configprop:spring.cache.cache-names[] 属性在启动时创建缓存。如果定义了自定义 ConfigurationBuilder
Bean,则使用它来自定义缓存。
Caches can be created on startup by setting the configprop:spring.cache.cache-names[] property.
If a custom ConfigurationBuilder
bean is defined, it is used to customize the caches.
为了兼容 Spring Boot 的 Jakarta EE 9 基线,必须使用 Infinispan 的 -jakarta
模块。对于具有 -jakarta
变体的每个模块,必须使用变体来代替标准模块。例如,必须分别使用 infinispan-core-jakarta
和 infinispan-commons-jakarta
来代替 infinispan-core
和 infinispan-commons
。
To be compatible with Spring Boot’s Jakarta EE 9 baseline, Infinispan’s -jakarta
modules must be used.
For every module with a -jakarta
variant, the variant must be used in place of the standard module.
For example, infinispan-core-jakarta
and infinispan-commons-jakarta
must be used in place of infinispan-core
and infinispan-commons
respectively.
Couchbase
如果 Spring Data Couchbase 可用且 Couchbase 是 configured,则会自动配置 CouchbaseCacheManager
。可以通过设置 configprop:spring.cache.cache-names[] 属性创建附加缓存,可使用 spring.cache.couchbase.*
属性配置缓存默认值。例如,以下配置使用 10 分钟的条目 expiration 创建 cache1
和 cache2
缓存:
If Spring Data Couchbase is available and Couchbase is configured, a CouchbaseCacheManager
is auto-configured.
It is possible to create additional caches on startup by setting the configprop:spring.cache.cache-names[] property and cache defaults can be configured by using spring.cache.couchbase.*
properties.
For instance, the following configuration creates cache1
and cache2
caches with an entry expiration of 10 minutes:
spring: cache: cache-names: "cache1,cache2" couchbase: expiration: "10m"
如果你需要对配置进行更多控制,可以考虑注册 CouchbaseCacheManagerBuilderCustomizer
Bean。以下示例显示了一个自定义程序,它为 cache1
和 cache2
配置了一个特定的条目过期时间:
If you need more control over the configuration, consider registering a CouchbaseCacheManagerBuilderCustomizer
bean.
The following example shows a customizer that configures a specific entry expiration for cache1
and cache2
:
Redis
如果 Redis 可用且已配置,则会自动配置 RedisCacheManager
。可以通过设置 configprop:spring.cache.cache-names[] 属性创建附加缓存,可使用 spring.cache.redis.*
属性配置缓存默认值。例如,以下配置使用 10 分钟的 time to live 创建 cache1
和 cache2
缓存:
If Redis is available and configured, a RedisCacheManager
is auto-configured.
It is possible to create additional caches on startup by setting the configprop:spring.cache.cache-names[] property and cache defaults can be configured by using spring.cache.redis.*
properties.
For instance, the following configuration creates cache1
and cache2
caches with a time to live of 10 minutes:
spring: cache: cache-names: "cache1,cache2" redis: time-to-live: "10m"
默认情况下,会添加一个键前缀,以便如果两个单独的缓存使用相同的键,Redis 不会有重叠的键并且无法返回无效的值。如果你创建自己的 |
By default, a key prefix is added so that, if two separate caches use the same key, Redis does not have overlapping keys and cannot return invalid values.
We strongly recommend keeping this setting enabled if you create your own |
你可以通过添加自己的 |
You can take full control of the default configuration by adding a |
如果你需要对配置进行更多控制,可以考虑注册 RedisCacheManagerBuilderCustomizer
Bean。以下示例显示了一个自定义程序,它为 cache1
和 cache2
配置了一个特定的生存时间:
If you need more control over the configuration, consider registering a RedisCacheManagerBuilderCustomizer
bean.
The following example shows a customizer that configures a specific time to live for cache1
and cache2
:
Caffeine
Caffeine是Guava缓存的Java8重写,它取代了对Guava的支持。如果Caffeine存在,将`CaffeineCacheManager`(由`spring-boot-starter-cache`"`Starter`"提供)自动配置。可以通过设置configprop:spring.cache.cache-names[]属性来在启动时创建缓存,并且可以通过以下方式之一(按指示的顺序)进行自定义:
Caffeine is a Java 8 rewrite of Guava’s cache that supersedes support for Guava.
If Caffeine is present, a CaffeineCacheManager
(provided by the spring-boot-starter-cache
“Starter”) is auto-configured.
Caches can be created on startup by setting the configprop:spring.cache.cache-names[] property and can be customized by one of the following (in the indicated order):
-
A cache spec defined by
spring.cache.caffeine.spec
-
A
com.github.benmanes.caffeine.cache.CaffeineSpec
bean is defined -
A
com.github.benmanes.caffeine.cache.Caffeine
bean is defined
例如,下列配置使用最大大小为500和_time to live_为10分钟的创建`cache1`和`cache2`缓存:
For instance, the following configuration creates cache1
and cache2
caches with a maximum size of 500 and a time to live of 10 minutes
spring: cache: cache-names: "cache1,cache2" caffeine: spec: "maximumSize=500,expireAfterAccess=600s"
如果定义了`com.github.benmanes.caffeine.cache.CacheLoader`bean,则它会自动与`CaffeineCacheManager`关联。由于`CacheLoader`将与缓存管理器管理的_all_缓存相关联,因此必须将其定义为`CacheLoader<Object, Object>`。自动配置忽略任何其他通用类型。
If a com.github.benmanes.caffeine.cache.CacheLoader
bean is defined, it is automatically associated to the CaffeineCacheManager
.
Since the CacheLoader
is going to be associated with all caches managed by the cache manager, it must be defined as CacheLoader<Object, Object>
.
The auto-configuration ignores any other generic type.
Cache2k
Cache2k是一个内存缓存。如果存在Cache2k Spring集成,则自动配置`SpringCache2kCacheManager`。
Cache2k is an in-memory cache.
If the Cache2k spring integration is present, a SpringCache2kCacheManager
is auto-configured.
可以通过设置configprop:spring.cache.cache-names[]属性来在启动时创建缓存。可以使用`Cache2kBuilderCustomizer`bean自定义缓存默认值。以下示例显示了一个定制器,它将缓存的容量配置为200个条目,到期时间为5分钟:
Caches can be created on startup by setting the configprop:spring.cache.cache-names[] property.
Cache defaults can be customized using a Cache2kBuilderCustomizer
bean.
The following example shows a customizer that configures the capacity of the cache to 200 entries, with an expiration of 5 minutes:
Simple
如果找不到任何其他提供程序,则配置使用`ConcurrentHashMap`作为缓存存储的简单实现。如果应用程序中不存在缓存库,则这是默认设置。默认情况下,会根据需要创建缓存,但是你可以通过设置`cache-names`属性来限制可用缓存的列表。例如,如果你只想保留`cache1`和`cache2`缓存,请按如下方式设置`cache-names`属性:
If none of the other providers can be found, a simple implementation using a ConcurrentHashMap
as the cache store is configured.
This is the default if no caching library is present in your application.
By default, caches are created as needed, but you can restrict the list of available caches by setting the cache-names
property.
For instance, if you want only cache1
and cache2
caches, set the cache-names
property as follows:
spring: cache: cache-names: "cache1,cache2"
如果你这样做并且你的应用程序使用了未列出的缓存,那么在需要缓存时(而不是在启动时)运行时会失败。这类似于在你使用未申报的缓存时,“实际”缓存提供程序的行为方式。
If you do so and your application uses a cache not listed, then it fails at runtime when the cache is needed, but not on startup. This is similar to the way the "real" cache providers behave if you use an undeclared cache.
None
当`@EnableCaching`存在于你的配置中时,也需要适当的缓存配置。如果你有自定义`CacheManager`,请考虑在单独的`@Configuration`类中对其进行定义,以便在必要时可以覆盖它。None使用无操作实现,这在测试中很有用,切片测试通过`@AutoConfigureCache`默认使用它。
When @EnableCaching
is present in your configuration, a suitable cache configuration is expected as well.
If you have a custom CacheManager
, consider defining it in a separate @Configuration
class so that you can override it if necessary.
None uses a no-op implementation that is useful in tests, and slice tests use that by default via @AutoConfigureCache
.
如果你需要在特定环境中使用无操作缓存,而不是自动配置的缓存管理器,请将缓存类型设置为`none`,如下例所示:
If you need to use a no-op cache rather than the auto-configured cache manager in a certain environment, set the cache type to none
, as shown in the following example:
spring: cache: type: "none"