Configuring the Cache Storage
缓存抽象提供了多种存储集成选项。要使用它们,您需要声明一个适当的 CacheManager
(一个控制和管理 Cache
实例且可用于检索它们以进行存储的实体)。
The cache abstraction provides several storage integration options. To use them, you need
to declare an appropriate CacheManager
(an entity that controls and manages Cache
instances and that can be used to retrieve these for storage).
JDK ConcurrentMap
-based Cache
基于 JDK 的 Cache
实现位于 org.springframework.cache.concurrent
包中。它使你可以使用 ConcurrentHashMap
作为支持 Cache
存储。以下示例演示如何配置两个缓存:
The JDK-based Cache
implementation resides under
org.springframework.cache.concurrent
package. It lets you use ConcurrentHashMap
as a backing Cache
store. The following example shows how to configure two caches:
-
Java
-
Kotlin
-
Xml
@Bean
ConcurrentMapCacheFactoryBean defaultCache() {
ConcurrentMapCacheFactoryBean cache = new ConcurrentMapCacheFactoryBean();
cache.setName("default");
return cache;
}
@Bean
ConcurrentMapCacheFactoryBean booksCache() {
ConcurrentMapCacheFactoryBean cache = new ConcurrentMapCacheFactoryBean();
cache.setName("books");
return cache;
}
@Bean
CacheManager cacheManager(ConcurrentMapCache defaultCache, ConcurrentMapCache booksCache) {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Set.of(defaultCache, booksCache));
return cacheManager;
}
@Bean
fun defaultCache(): ConcurrentMapCacheFactoryBean {
return ConcurrentMapCacheFactoryBean().apply {
setName("default")
}
}
@Bean
fun booksCache(): ConcurrentMapCacheFactoryBean {
return ConcurrentMapCacheFactoryBean().apply {
setName("books")
}
}
@Bean
fun cacheManager(defaultCache: ConcurrentMapCache, booksCache: ConcurrentMapCache): CacheManager {
return SimpleCacheManager().apply {
setCaches(setOf(defaultCache, booksCache))
}
}
<!-- simple cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="default"/>
<bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" name="books"/>
</set>
</property>
</bean>
前一代码段使用`SimpleCacheManager`创建一个`CacheManager`用于两个嵌套的`ConcurrentMapCache`,实例名为`default`和`books`。请注意,名称是针对每个缓存直接配置的。
The preceding snippet uses the SimpleCacheManager
to create a CacheManager
for the
two nested ConcurrentMapCache
instances named default
and books
. Note that the
names are configured directly for each cache.
由于缓存是由应用程序创建的,因此它与应用程序的生命周期绑定,使其适合基本用例、测试或简单应用程序。缓存扩展性好并且非常快,但它不提供任何管理功能、持久性功能或驱逐协定。
As the cache is created by the application, it is bound to its lifecycle, making it suitable for basic use cases, tests, or simple applications. The cache scales well and is very fast, but it does not provide any management, persistence capabilities, or eviction contracts.
Ehcache-based Cache
Ehcache 3.x 完全符合 JSR-107,不需要针对它提供专属支持。有关详细信息,请参见 JSR-107 Cache。
Ehcache 3.x is fully JSR-107 compliant and no dedicated support is required for it. See JSR-107 Cache for details.
Caffeine Cache
Caffeine是Guava 缓存的 Java 8 重写版本,其实现位于`org.springframework.cache.caffeine`包中,并且提供对 Caffeine 的若干功能的访问权限。
Caffeine is a Java 8 rewrite of Guava’s cache, and its implementation is located in the
org.springframework.cache.caffeine
package and provides access to several features
of Caffeine.
以下示例配置了一个按需创建缓存的`CacheManager`:
The following example configures a CacheManager
that creates the cache on demand:
-
Java
-
Kotlin
-
Xml
@Bean
CacheManager cacheManager() {
return new CaffeineCacheManager();
}
@Bean
fun cacheManager(): CacheManager {
return CaffeineCacheManager()
}
<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager"/>
你还可以显式提供要使用的缓存。在这种情况下,只有那些缓存是由管理器提供的。以下示例展示了如何这样做:
You can also provide the caches to use explicitly. In that case, only those are made available by the manager. The following example shows how to do so:
-
Java
-
Kotlin
-
Xml
@Bean
CacheManager cacheManager() {
CaffeineCacheManager cacheManager = new CaffeineCacheManager();
cacheManager.setCacheNames(List.of("default", "books"));
return cacheManager;
}
@Bean
fun cacheManager(): CacheManager {
return CaffeineCacheManager().apply {
cacheNames = listOf("default", "books")
}
}
<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager">
<property name="cacheNames">
<set>
<value>default</value>
<value>books</value>
</set>
</property>
</bean>
Caffeine CacheManager
还支持自定义 Caffeine
和 CacheLoader
。有关它们的详细信息,请参见 Caffeine documentation。
The Caffeine CacheManager
also supports custom Caffeine
and CacheLoader
.
See the Caffeine documentation
for more information about those.
GemFire-based Cache
GemFire 是面向内存、支持磁盘、弹性可缩放、持续可用,主动(带有基于内置模式的订阅通知)的全局复制数据库,并提供功能齐全的边缘缓存。有关如何将 GemFire 用作 `CacheManager`的详细信息(以及更多其他信息),请参见https://docs.spring.io/spring-gemfire/docs/current/reference/html/[Spring Data GemFire 参考文档]。
GemFire is a memory-oriented, disk-backed, elastically scalable, continuously available,
active (with built-in pattern-based subscription notifications), globally replicated
database and provides fully-featured edge caching. For further information on how to
use GemFire as a CacheManager
(and more), see the
Spring Data GemFire reference documentation.
JSR-107 Cache
Spring的缓存抽象还可以使用符合 JSR-107 的缓存。JCache 实现位于`org.springframework.cache.jcache`包中。
Spring’s caching abstraction can also use JSR-107-compliant caches. The JCache
implementation is located in the org.springframework.cache.jcache
package.
同样,要使用它,你需要声明合适的`CacheManager`。以下示例展示了如何这样做:
Again, to use it, you need to declare the appropriate CacheManager
.
The following example shows how to do so:
-
Java
-
Kotlin
-
Xml
@Bean
javax.cache.CacheManager jCacheManager() {
CachingProvider cachingProvider = Caching.getCachingProvider();
return cachingProvider.getCacheManager();
}
@Bean
org.springframework.cache.CacheManager cacheManager(javax.cache.CacheManager jCacheManager) {
return new JCacheCacheManager(jCacheManager);
}
@Bean
fun jCacheManager(): javax.cache.CacheManager {
val cachingProvider = Caching.getCachingProvider()
return cachingProvider.getCacheManager()
}
@Bean
fun cacheManager(jCacheManager: javax.cache.CacheManager): org.springframework.cache.CacheManager {
return JCacheCacheManager(jCacheManager)
}
<bean id="cacheManager"
class="org.springframework.cache.jcache.JCacheCacheManager"
p:cache-manager-ref="jCacheManager"/>
<!-- JSR-107 cache manager setup -->
<bean id="jCacheManager" .../>
Dealing with Caches without a Backing Store
有时候,在切换环境或进行测试时,你可能会有缓存声明,而没有配置实际的支持缓存。由于这是一个无效配置,因此会在运行时抛出异常,因为缓存基础设施找不到合适的存储。在这种情况下,你可以接入一个简单的虚拟缓存,而不是删除缓存声明(这可能很繁琐),该缓存不执行任何缓存——即每次都强制调用被缓存的方法。以下示例展示了如何这样做:
Sometimes, when switching environments or doing testing, you might have cache declarations without having an actual backing cache configured. As this is an invalid configuration, an exception is thrown at runtime, since the caching infrastructure is unable to find a suitable store. In situations like this, rather than removing the cache declarations (which can prove tedious), you can wire in a simple dummy cache that performs no caching — that is, it forces the cached methods to be invoked every time. The following example shows how to do so:
-
Java
-
Kotlin
-
Xml
@Bean
CacheManager cacheManager(CacheManager jdkCache, CacheManager gemfireCache) {
CompositeCacheManager cacheManager = new CompositeCacheManager();
cacheManager.setCacheManagers(List.of(jdkCache, gemfireCache));
cacheManager.setFallbackToNoOpCache(true);
return cacheManager;
}
@Bean
fun cacheManager(jdkCache: CacheManager, gemfireCache: CacheManager): CacheManager {
return CompositeCacheManager().apply {
setCacheManagers(listOf(jdkCache, gemfireCache))
setFallbackToNoOpCache(true)
}
}
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
<property name="cacheManagers">
<list>
<ref bean="jdkCache"/>
<ref bean="gemfireCache"/>
</list>
</property>
<property name="fallbackToNoOpCache" value="true"/>
</bean>
前面的`CompositeCacheManager`链接了多个`CacheManager`实例,并且通过`fallbackToNoOpCache`标志,为所有未经配置的缓存管理器处理的定义添加了一个无操作缓存。即,每个在`jdkCache`或`gemfireCache`(在示例中前面配置)中找不到的缓存定义都由无操作缓存处理,该缓存不存储任何信息,导致每次都会调用目标方法。
The CompositeCacheManager
in the preceding chains multiple CacheManager
instances and,
through the fallbackToNoOpCache
flag, adds a no-op cache for all the definitions not
handled by the configured cache managers. That is, every cache definition not found in
either jdkCache
or gemfireCache
(configured earlier in the example) is handled by
the no-op cache, which does not store any information, causing the target method to be
invoked every time.