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.注意事项
- Caffeine 不直接支持获取缓存中的所有 key(getKeys()方法),如果需要此功能,需自行维护 key 集合
- 缓存配置(过期时间等)可以针对不同缓存名称单独配置,需要额外扩展
- 移除了allowNullValues的支持,建议缓存中不存储 null 值
5.性能优势
- Caffeine 基于 Java 8,使用更高效的算法(W-TinyLFU)
- 平均访问时间更短,内存占用更优
- 支持异步加载等高级特性(如需可扩展实现)