Configuring the Cache Storage

缓存抽象提供了多种存储集成选项。要使用它们,您需要声明一个适当的 CacheManager(一个控制和管理 Cache 实例且可用于检索它们以进行存储的实体)。

JDK ConcurrentMap-based Cache

基于 JDK 的 Cache 实现位于 org.springframework.cache.concurrent 包中。它使你可以使用 ConcurrentHashMap 作为支持 Cache 存储。以下示例演示如何配置两个缓存:

  • 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`。请注意,名称是针对每个缓存直接配置的。

由于缓存是由应用程序创建的,因此它与应用程序的生命周期绑定,使其适合基本用例、测试或简单应用程序。缓存扩展性好并且非常快,但它不提供任何管理功能、持久性功能或驱逐协定。

Ehcache-based Cache

Ehcache 3.x 完全符合 JSR-107,不需要针对它提供专属支持。有关详细信息,请参见 JSR-107 Cache

Caffeine Cache

Caffeine是Guava 缓存的 Java 8 重写版本,其实现位于`org.springframework.cache.caffeine`包中,并且提供对 Caffeine 的若干功能的访问权限。

以下示例配置了一个按需创建缓存的`CacheManager`:

  • Java

  • Kotlin

  • Xml

@Bean
CacheManager cacheManager() {
	return new CaffeineCacheManager();
}
@Bean
fun cacheManager(): CacheManager {
	return CaffeineCacheManager()
}
<bean id="cacheManager" class="org.springframework.cache.caffeine.CaffeineCacheManager"/>

你还可以显式提供要使用的缓存。在这种情况下,只有那些缓存是由管理器提供的。以下示例展示了如何这样做:

  • 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 还支持自定义 CaffeineCacheLoader。有关它们的详细信息,请参见 Caffeine documentation

GemFire-based Cache

GemFire 是面向内存、支持磁盘、弹性可缩放、持续可用,主动(带有基于内置模式的订阅通知)的全局复制数据库,并提供功能齐全的边缘缓存。有关如何将 GemFire 用作 `CacheManager`的详细信息(以及更多其他信息),请参见https://docs.spring.io/spring-gemfire/docs/current/reference/html/[Spring Data GemFire 参考文档]。

JSR-107 Cache

Spring的缓存抽象还可以使用符合 JSR-107 的缓存。JCache 实现位于`org.springframework.cache.jcache`包中。

同样,要使用它,你需要声明合适的`CacheManager`。以下示例展示了如何这样做:

  • 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

有时候,在切换环境或进行测试时,你可能会有缓存声明,而没有配置实际的支持缓存。由于这是一个无效配置,因此会在运行时抛出异常,因为缓存基础设施找不到合适的存储。在这种情况下,你可以接入一个简单的虚拟缓存,而不是删除缓存声明(这可能很繁琐),该缓存不执行任何缓存——即每次都强制调用被缓存的方法。以下示例展示了如何这样做:

  • 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`(在示例中前面配置)中找不到的缓存定义都由无操作缓存处理,该缓存不存储任何信息,导致每次都会调用目标方法。