1. 概述

本文将带你了解 JetCache 这个强大的缓存抽象库。我们将探讨它的核心能力、适用场景以及具体使用方法。

JetCache 是一个缓存抽象层,允许我们在多种缓存实现之上构建统一接口。这意味着我们可以编写与具体缓存实现无关的代码,随时切换底层缓存框架而无需修改业务逻辑。

2. 依赖配置

使用 JetCache 前,需要先引入 最新版本(当前为 2.7.6)

根据需求选择不同依赖模块,核心功能位于 com.alicp.jetcache:jetcache-core。Maven 配置如下:

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-core</artifactId>
    <version>2.7.6</version>
</dependency>

⚠️ 核心库已内置两种内存缓存:

  • LinkedHashMapCache:基于 java.util.LinkedHashMap
  • CaffeineCache:基于 Caffeine 高性能缓存库

如需其他缓存实现(如 Redis),需额外引入对应依赖。

3. 手动操作缓存

3.1. 创建缓存实例

**创建缓存需明确指定实现类型,并使用对应的 Builder 模式**。例如构建 LinkedHashMapCache

Cache<Integer, String> cache = LinkedHashMapCacheBuilder.createLinkedHashMapCacheBuilder()
  .limit(100)
  .expireAfterWrite(10, TimeUnit.SECONDS)
  .buildCache();

✅ 不同缓存框架配置项可能不同,但 JetCache 统一暴露 Cache<K, V> 接口。切换实现只需修改 Builder:

Cache<Integer, String> cache = CaffeineCacheBuilder.createCaffeineCacheBuilder()
  .limit(100)
  .expireAfterWrite(10, TimeUnit.SECONDS)
  .buildCache();

3.2. 缓存存取操作

获取缓存实例后,可直接进行数据存取

cache.put(1, "Hello");
assertEquals("Hello", cache.get(1));

❌ 当缓存未命中时,get() 返回 null(可能因过期或容量淘汰)。建议使用 GET() 获取详细状态:

// 已过期的情况
assertEquals(CacheResultCode.EXPIRED, cache.GET(1).getResultCode());

// 从未存在的情况
assertEquals(CacheResultCode.NOT_EXISTS, cache.GET(2).getResultCode());

⚠️ 不同缓存库返回的状态码可能不同(如 Caffeine 无法区分过期和不存在)。手动清理缓存使用:

cache.remove(1);

3.3. 批量操作

支持批量操作提升效率,批量写入需传入 Map<K, V>

Map<Integer, String> putMap = new HashMap<>();
putMap.put(1, "One");
putMap.put(2, "Two");
putMap.put(3, "Three");
cache.putAll(putMap);

批量读取通过 Set<K> 指定键集合,返回存在的键值对:

Map<Integer, String> values = cache.getAll(keys);

批量删除操作:

cache.removeAll(keys);

4. Spring Boot 集成

4.1. 基础配置

**JetCache 提供 Spring Boot 自动配置**,只需添加依赖:

<dependency>
    <groupId>com.alicp.jetcache</groupId>
    <artifactId>jetcache-autoconfigure</artifactId>
    <version>2.7.6</version>
</dependency>

✅ 启动时自动加载配置。如需特定缓存实现(如 Redis),可添加对应 Starter

4.2. 编程式缓存使用

集成后自动暴露 com.alicp.jetcache.CacheManager Bean,通过它创建缓存:

QuickConfig quickConfig = QuickConfig.newBuilder("testing")
  .cacheType(CacheType.LOCAL)
  .expire(Duration.ofSeconds(100))
  .build();
Cache<Integer, String> cache = cacheManager.getOrCreateCache(quickConfig);

可在 @Bean 定义或组件中直接使用。缓存按名称注册,支持直接从 CacheManager 获取。

区分本地缓存(LOCAL)和远程缓存(REMOTE)

  • 本地缓存:应用内内存缓存(如 Caffeine)
  • 远程缓存:外部基础设施(如 Redis)

未指定类型时,JetCache 自动创建 两级缓存(本地+远程),兼顾性能与共享性。

4.3. 配置文件管理

通过 application.properties 统一管理配置(非必需,有默认值):

jetcache.local.default.type=linkedhashmap
jetcache.remote.default.type=redis.lettuce
jetcache.remote.default.uri=redis://127.0.0.1:6379/

✅ 避免硬编码,支持动态调整。

5. 方法级缓存

5.1. 方法结果缓存

通过注解实现方法级缓存,需先启用:

@Configuration
@EnableMethodCache(basePackages = "com.baeldung.jetcache")
public class Application {}

在方法上添加 @Cached

@Cached
public String doSomething(int i) {
    // .....
}

✅ 默认行为:

  • 缓存名 = 方法全限定签名(避免冲突)
  • 键 = 所有方法参数
  • 同时启用本地+远程缓存

自定义配置示例:

@Cached(cacheType = CacheType.LOCAL, expire = 3600, timeUnit = TimeUnit.SECONDS, localLimit = 100)

使用 SpEL 指定缓存键:

@Cached(name="userCache", key="#userId", expire = 3600)
User getUserById(long userId) {
    // .....
}

⚠️ 需编译时添加 -parameters 参数,否则使用 args[0] 按位置引用。

5.2. 缓存更新与失效

通过注解管理缓存生命周期

  1. 失效缓存(@CacheInvalidate): ```java @Cached(name="userCache", key="#userId", expire = 3600) User getUserById(long userId) { // ..... }

@CacheInvalidate(name = "userCache", key = "#userId") void deleteUserById(long userId) { // ..... }


2. 更新缓存(`@CacheUpdate`):
```java
@Cached(name="userCache", key="#userId", expire = 3600)
User getUserById(long userId) {
    // .....
}

@CacheUpdate(name = "userCache", key = "#user.userId", value = "#user")
void updateUser(User user) {
    // .....
}

@CacheUpdate 总是执行方法体,并在执行后更新缓存。

6. 总结

JetCache 提供了灵活的缓存抽象方案,支持:

  • 多种缓存实现统一接口
  • 两级缓存(本地+远程)优化性能
  • Spring Boot 深度集成
  • 方法级注解缓存

本文仅覆盖核心功能,更多高级特性(如异步加载、监控等)建议参考 官方文档 或实践 GitHub 示例


原始标题:Introduction to JetCache | Baeldung