配置缓存存储
缓存抽象提供了多种存储集成选项。要使用它们,您需要声明一个适当的 CacheManager(一个控制和管理 Cache 实例并可用于检索这些实例以进行存储的实体)。
基于 JDK ConcurrentMap 的缓存
基于 JDK 的 Cache 实现位于 infra.cache.concurrent 包下。它允许您使用 ConcurrentHashMap 作为后备 Cache 存储。以下示例显示了如何配置两个缓存:
<!-- simple cache manager -->
<bean id="cacheManager" class="infra.cache.support.SimpleCacheManager">
<property name="caches">
<set>
<bean class="infra.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default"/>
<bean class="infra.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="books"/>
</set>
</property>
</bean>
前面的片段使用 SimpleCacheManager 为两个名为 default 和 books 的嵌套 ConcurrentMapCache 实例创建了一个 CacheManager。请注意,名称是为每个缓存直接配置的。
由于缓存是由应用程序创建的,因此它绑定到其生命周期,使其适用于基本用例、测试或简单的应用程序。该缓存具有良好的扩展性且速度非常快,但它不提供任何管理、持久性功能或驱逐契约。
基于 Ehcache 的缓存
Ehcache 3.x 完全符合 JSR-107 标准,不需要专门的支持。有关详细信息,请参阅 JSR-107 缓存。
Caffeine 缓存
Caffeine 是 Guava 缓存的 Java 8 重写版,其实现位于 infra.cache.caffeine 包中,并提供了对 Caffeine 多个功能的访问。
以下示例配置了一个按需创建缓存的 CacheManager:
<bean id="cacheManager"
class="infra.cache.caffeine.CaffeineCacheManager"/>
您还可以显式提供要使用的缓存。在这种情况下,管理器仅提供那些缓存。以下示例显示了如何执行此操作:
<bean id="cacheManager" class="infra.cache.caffeine.CaffeineCacheManager">
<property name="cacheNames">
<set>
<value>default</value>
<value>books</value>
</set>
</property>
</bean>
Caffeine CacheManager 还支持自定义 Caffeine 和 CacheLoader。
有关这些内容的更多信息,请参阅 Caffeine 文档。
基于 GemFire 的缓存
GemFire 是一个面向内存、支持磁盘、可弹性扩展、持续可用、主动(具有内置的基于模式的订阅通知)、全局复制的数据库,并提供功能齐全的边缘缓存。有关如何将 GemFire 用作 CacheManager(及更多内容)的更多信息。
JSR-107 缓存
Infra 缓存抽象也可以使用符合 JSR-107 标准的缓存。JCache 实现位于 infra.cache.jcache 包中。
同样,要使用它,您需要声明适当的 CacheManager。
以下示例显示了如何执行此操作:
<bean id="cacheManager"
class="infra.cache.jcache.JCacheCacheManager"
p:cache-manager-ref="jCacheManager"/>
<!-- JSR-107 cache manager setup -->
<bean id="jCacheManager" .../>
处理没有后备存储的缓存
有时,在切换环境或进行测试时,您可能会在没有配置实际后备缓存的情况下进行缓存声明。由于这是一个无效的配置,因此在运行时会抛出异常,因为缓存基础设施无法找到合适的存储。在这种情况下,与其删除缓存声明(这可能很繁琐),不如连接一个简单的虚拟缓存,该缓存不执行任何缓存操作——即,它强制每次都调用缓存的方法。 以下示例显示了如何执行此操作:
<bean id="cacheManager" class="infra.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(在示例前面配置)中未找到的每个缓存定义都由无操作缓存处理,该缓存不存储任何信息,导致每次都调用目标方法。