Skip to content

本地缓存

一、Caffeine

1.1 使用方式

这里介绍 Caffeine 作为本地缓存实现,它的底层实际上是使用 ConcurrentHashMap 进行实现的

xml
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>2.9.3</version>
</dependency>

操作API 参考:https://github.com/ben-manes/caffeine/wiki/Home-zh-CN

java
Cache<String, String> cache = Caffeine.newBuilder()
    // 设置缓存的过期时间 - 写入缓存之后多久过期
    .expireAfterWrite(10, TimeUnit.SECONDS)
    // 设置缓存的过期时间 - 如果多久没有访问,
    .expireAfterAccess(15, TimeUnit.SECONDS)
    // 设置缓存的最大大小
    .maximumSize(1)
    // 键值对移除的监听器,如果移除某个键值对,则会回调这个方法
    .removalListener((key, value, cause) -> {
        log.info("remove key:{},value:{},cause:{}", key, value, cause);
    })
    .build();

下面介绍一下,常用的方法

java
@Test
public void testCachePut() {
    // 方式一
    cache.put("key-1", "value-1");
    // 方式二
    Map<String, String> tem = new HashMap<>();
    tem.put("key-2", "value-2");
    tem.put("key-3", "value-3");
    cache.putAll(tem);
}
java
@Test
public void testCacheGet() {
    // 获取缓存值,如果没有对应的值,则会回调函数,将值放入到缓存之中,并返回
    String value1 = cache.get("key-1", key -> { return "value-1"; });
    Map<String, String> cacheAll = cache.getAll(Arrays.asList("key-1", "key-2"), keys -> {
        HashMap<String, String> tem = new HashMap<>();
        keys.forEach(key -> {
            tem.put(key, "value-" + key);
        });
        return tem;
    });

    // 获取缓存值,如果没有值,则返回null
    String value2 = cache.getIfPresent("key-2");
    Map<String, String> allPresent = cache.getAllPresent(Arrays.asList("key-1", "key-2"));
}
java
@Test
public void testDeleteCache() {
    // 删除某个元素
    cache.invalidate("key-1");
    // 删除多个元素
    cache.invalidateAll(Arrays.asList("key-1", "key-2"));
    // 删除全部元素
    cache.invalidateAll();
}

1.2 集成 SpringBoot

在 Redis 缓存篇,我们介绍了 spring-boot-starter-cache 组件,这里也可以配置 Caffeine 作为缓存工具

java
@Bean
public Caffeine<Object, Object> caffeineCache() {
    return Caffeine.newBuilder()
        // 在写入缓存之后,多久过期
        .expireAfterWrite(10, TimeUnit.SECONDS)
        // 在访问缓存之后,多久过期
        .expireAfterAccess(15, TimeUnit.SECONDS)
        // 初始的缓存空间大小
        .initialCapacity(100)
        // 缓存的最大条数
        .maximumSize(100);
}
@Bean
public CacheManager cacheManager() {
    CaffeineCacheManager cacheManager = new CaffeineCacheManager();
    cacheManager.setCaffeine(caffeineCache());
    return cacheManager;
}
yml
spring:
  cache:
    type: CAFFEINE