SpringBoot3中使用Caffeine缓存组件

SpringBoot3已经把EhCache从框架中删除了,SpringBoot3默认的缓存组件为Caffeine,那么我们在SpringBoot3中如何去使用它了?

1.添加依赖

xml 复制代码
<dependency>
    <groupId>com.github.ben-manes.caffeine</groupId>
    <artifactId>caffeine</artifactId>
    <version>3.1.8</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2.配置Caffeine缓存

创建Caffeine配置类

java 复制代码
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;

@Configuration
public class CaffeineConfig {

    /**
     * 配置Caffeine缓存管理器
     */
    @Bean
    public CacheManager cacheManager() {
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        // 设置缓存默认配置
        cacheManager.setCaffeine(caffeineCacheBuilder());
        // 允许动态创建缓存
        cacheManager.setAllowNullValues(false);
        return cacheManager;
    }

    /**
     * 配置Caffeine缓存属性
     * 可根据需要调整过期时间和最大缓存数量
     */
    Caffeine<Object, Object> caffeineCacheBuilder() {
        return Caffeine.newBuilder()
                // 最后一次写入后经过固定时间过期
                .expireAfterWrite(60, TimeUnit.MINUTES)
                // 最大缓存条目
                .maximumSize(10000)
                // 初始缓存容量
                .initialCapacity(100)
                // 记录缓存命中率等统计信息
                .recordStats();
    }
}

3.添加工具类

添加Caffeine工具类

java 复制代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.util.ObjectUtils;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class CaffeineUtils {
    private static final Logger logger = LoggerFactory.getLogger(CaffeineUtils.class);

    // 获取Spring管理的缓存管理器
    private static final CacheManager cacheManager = SpringUtils.getBean(CacheManager.class);

    // 默认缓存名称
    private static final String SYS_CACHE = "sys-cache";

    /**
     * 获取SYS_CACHE缓存
     */
    public static Object get(String key) {
        return get(SYS_CACHE, key);
    }

    /**
     * 获取SYS_CACHE缓存,带默认值
     */
    public static Object get(String key, Object defaultValue) {
        Object value = get(key);
        return value != null ? value : defaultValue;
    }

    /**
     * 写入SYS_CACHE缓存
     */
    public static void put(String key, Object value) {
        put(SYS_CACHE, key, value);
    }

    /**
     * 从SYS_CACHE缓存中移除
     */
    public static void remove(String key) {
        remove(SYS_CACHE, key);
    }


    /**
     * 从SYS_CACH缓存中移除指定key集合
     */
    public static void removeByKeys(Set<String> keys) {
        removeByKeys(SYS_CACHE, keys);
    }

    /**
     * 获取指定缓存
     */
    public static Object get(String cacheName, String key) {
        Cache cache = getCache(cacheName);
        Cache.ValueWrapper wrapper = cache.get(getKey(key));
        return wrapper != null ? wrapper.get() : null;
    }

    /**
     * 获取指定缓存,带默认值
     */
    public static Object get(String cacheName, String key, Object defaultValue) {
        Object value = get(cacheName, key);
        return value != null ? value : defaultValue;
    }

    /**
     * 写入指定缓存
     */
    public static void put(String cacheName, String key, Object value) {
        if (value != null) {
            getCache(cacheName).put(getKey(key), value);
        }
    }

    /**
     * 从指定缓存中移除
     */
    public static void remove(String cacheName, String key) {
        getCache(cacheName).evict(getKey(key));
    }

    /**
     * 清空指定缓存
     */
    public static void removeAll(String cacheName) {
        Cache cache = getCache(cacheName);
        // Caffeine不直接支持获取所有key,如需此功能需自行维护key集合
        cache.clear();
        logger.info("清理缓存:{}", cacheName);
    }

    /**
     * 从指定缓存中移除指定key集合
     */
    public static void removeByKeys(String cacheName, Set<String> keys) {
        Cache cache = getCache(cacheName);
        for (String key : keys) {
            cache.evict(getKey(key));
        }
        logger.info("清理缓存:{} => {}", cacheName, keys);
    }

    /**
     * 获取缓存键名
     */
    private static String getKey(String key) {
        return key;
    }

    /**
     * 获取缓存实例
     */
    public static Cache getCache(String cacheName) {
        Cache cache = cacheManager.getCache(cacheName);
        if (cache == null) {
            throw new RuntimeException("当前系统中没有定义"" + cacheName + ""这个缓存。");
        }
        return cache;
    }

    /**
     * 获取所有缓存名称
     */
    public static String[] getCacheNames() {
        return cacheManager.getCacheNames().toArray(new String[0]);
    }
}

4.注意事项

  1. Caffeine 不直接支持获取缓存中的所有 key(getKeys()方法),如果需要此功能,需自行维护 key 集合
  2. 缓存配置(过期时间等)可以针对不同缓存名称单独配置,需要额外扩展
  3. 移除了allowNullValues的支持,建议缓存中不存储 null 值

5.性能优势

  1. Caffeine 基于 Java 8,使用更高效的算法(W-TinyLFU)
  2. 平均访问时间更短,内存占用更优
  3. 支持异步加载等高级特性(如需可扩展实现)
相关推荐
智购科技无人售货机厂家6 小时前
2026自动售货机制冷系统维护指南:从散热器清洁到压缩机换油的工程实践~YH
运维·redis·物联网·缓存·架构
EXI-小洲6 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
2601_961901707 小时前
SpringBoot使用Nacos进行application.yml配置管理
java·spring boot·spring
何以解忧,唯有..8 小时前
LangChain 工具调用(Tool Calling)实战指南
java·前端·langchain
QQ_21696290968 小时前
【源码编号:project79475】SpringBoot校内二手交易平台:商品发布、分类检索、留言交流、订单管理全流程实战
java·spring boot·后端
玉&心9 小时前
GraalVM 21 Native Image 编译踩坑全记录:从 class 初始化冲突到成功构建
ai·springboot·graalvm·rag
前端 贾公子9 小时前
第09章:上下文与记忆 (2)
java·服务器·前端
2601_9622035110 小时前
Java进阶07集合(续)
java·开发语言
郑州光合科技余经理10 小时前
本地生活服务系统:模块边界与结算字段怎么拆
java·开发语言·前端·后端·系统架构·uni-app·php
roman_日积跬步-终至千里10 小时前
【数据治理(6)】DataOps 不是调度工具,而是让数据产品长期可信的运行机制
java·服务器·网络