1. 概述
简单来说,JCache 是 Java 的标准缓存 API。本文将深入探讨 JCache 的核心概念及实际应用场景,帮助开发者快速掌握其精髓。
2. Maven 依赖
要在项目中使用 JCache,需在 pom.xml 添加以下依赖:
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.1.1</version>
</dependency>
✅ 最新版本可在 Maven 中央仓库 查询
同时需要添加具体实现(本文以 Hazelcast 为例):
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>5.2.0</version>
</dependency>
✅ Hazelcast 最新版本见 Maven 中央仓库
3. 主流实现方案
JCache 已被多种缓存解决方案实现:
- JCache 参考实现
- Hazelcast
- Oracle Coherence
- Terracotta Ehcache
- Infinispan
- Redisson
- Apache Ignite
⚠️ 重要提醒:JCache 参考实现存在并发问题,生产环境强烈不推荐使用!
4. 核心组件
4.1. Cache 接口
提供以下核心方法:
-
get()
- 根据键获取值,键不存在返回 null -
getAll()
- 批量获取多个键值对,返回 Map -
getAndRemove()
- 获取值后立即删除条目 -
put()
- 插入新条目 -
clear()
- 清空所有缓存 -
containsKey()
- 检查键是否存在
这些方法名已具备自解释性,完整文档见 Javadoc
4.2. CacheManager
最核心的接口之一,负责:
- 创建缓存实例
- 配置缓存参数
- 管理缓存生命周期
4.3. CachingProvider
用于管理 CacheManager 的生命周期:
- 创建 CacheManager 实例
- 控制 CacheManager 的初始化与销毁
4.4. Configuration
缓存配置接口,包含:
- 具体实现类:
MutableConfiguration
- 子接口:
CompleteConfiguration
5. 创建缓存实例
创建简单缓存的完整流程:
CachingProvider cachingProvider = Caching.getCachingProvider();
CacheManager cacheManager = cachingProvider.getCacheManager();
MutableConfiguration<String, String> config
= new MutableConfiguration<>();
Cache<String, String> cache = cacheManager
.createCache("simpleCache", config);
cache.put("key1", "value1");
cache.put("key2", "value2");
cacheManager.close();
执行步骤:
- 通过
CachingProvider
创建CacheManager
- 使用
MutableConfiguration
构建配置 - 创建
Cache
实例 - 存入缓存数据
- 关闭
CacheManager
释放资源
❌ 踩坑提醒:若未添加 JCache 实现,会抛出以下异常:
javax.cache.CacheException: No CachingProviders have been configured
原因:JVM 无法找到
getCacheManager()
的具体实现
6. EntryProcessor 原子操作
EntryProcessor
支持原子化修改缓存条目,无需重新添加:
public class SimpleEntryProcessor
implements EntryProcessor<String, String, String>, Serializable {
public String process(MutableEntry<String, String> entry, Object... args)
throws EntryProcessorException {
if (entry.exists()) {
String current = entry.getValue();
entry.setValue(current + " - modified");
return current;
}
return null;
}
}
使用示例:
@Test
public void whenModifyValue_thenCorrect() {
this.cache.invoke("key", new SimpleEntryProcessor());
assertEquals("value - modified", cache.get("key"));
}
7. 事件监听机制
通过事件监听器可响应以下事件类型:
-
CREATED
- 条目创建 -
UPDATED
- 条目更新 -
REMOVED
- 条目删除 -
EXPIRED
- 条目过期
实现监听器示例:
public class SimpleCacheEntryListener implements
CacheEntryCreatedListener<String, String>,
CacheEntryUpdatedListener<String, String>,
Serializable {
private boolean updated;
private boolean created;
// 标准 getter 方法
public void onUpdated(
Iterable<CacheEntryEvent<? extends String,
? extends String>> events) throws CacheEntryListenerException {
this.updated = true;
}
public void onCreated(
Iterable<CacheEntryEvent<? extends String,
? extends String>> events) throws CacheEntryListenerException {
this.created = true;
}
}
测试用例:
@Test
public void whenRunEvent_thenCorrect() throws InterruptedException {
this.listenerConfiguration
= new MutableCacheEntryListenerConfiguration<String, String>(
FactoryBuilder.factoryOf(this.listener), null, false, true);
this.cache.registerCacheEntryListener(this.listenerConfiguration);
assertEquals(false, this.listener.getCreated());
this.cache.put("key", "value");
assertEquals(true, this.listener.getCreated());
assertEquals(false, this.listener.getUpdated());
this.cache.put("key", "newValue");
assertEquals(true, this.listener.getUpdated());
}
8. CacheLoader 读取穿透
CacheLoader
实现读取穿透模式,将缓存作为主数据源:
public class SimpleCacheLoader
implements CacheLoader<Integer, String> {
public String load(Integer key) throws CacheLoaderException {
return "fromCache" + key;
}
public Map<Integer, String> loadAll(Iterable<? extends Integer> keys)
throws CacheLoaderException {
Map<Integer, String> data = new HashMap<>();
for (int key : keys) {
data.put(key, load(key));
}
return data;
}
}
集成测试:
public class CacheLoaderIntegrationTest {
private Cache<Integer, String> cache;
@Before
public void setup() {
CachingProvider cachingProvider = Caching.getCachingProvider();
CacheManager cacheManager = cachingProvider.getCacheManager();
MutableConfiguration<Integer, String> config
= new MutableConfiguration<>()
.setReadThrough(true)
.setCacheLoaderFactory(new FactoryBuilder.SingletonFactory<>(
new SimpleCacheLoader()));
this.cache = cacheManager.createCache("SimpleCache", config);
}
@Test
public void whenReadingFromStorage_thenCorrect() {
for (int i = 1; i < 4; i++) {
String value = cache.get(i);
assertEquals("fromCache" + i, value);
}
}
}
9. 总结
本文系统介绍了 JCache 的核心概念与实战技巧:
- 标准化缓存 API 的优势
- 核心组件的协作机制
- 原子操作与事件监听实现
- 读取穿透模式的最佳实践
完整示例代码见 GitHub 仓库