需求背景:spring cache 使用多级缓存,缓存实现方式用redis时,默认存储的结构是string,结果,但项目中需要使用其他结果,于是想到自己定义一个实现类,然后根据类型进行切换不同的实现方式,于是乎有了下面多结构缓存管理器,核心方法是createRedisCache
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import java.util.Map;
import java.util.Objects;
/**
* 支持多结构的 Redis 缓存管理器
* 可根据缓存名前缀自动选择缓存结构(Hash/ZSet/普通字符串)
*/
public class StructRedisCacheManager extends RedisCacheManager {
// 缓存结构类型枚举
public enum CacheStructType {
HASH, // Hash 结构
ZSET, // ZSet 结构
STRING // 普通字符串结构(默认)
}
// 结构前缀(用于标识缓存类型,例如 "hash:userCache" 表示 Hash 结构)
private static final String HASH_PREFIX = "hash:";
private static final String ZSET_PREFIX = "zset:";
private final RedisConnectionFactory connectionFactory;
// 各结构的默认配置(是否允许覆盖/重复)
private final boolean hashAllowOverwrite; // Hash 是否允许覆盖
private final boolean zsetAllowDuplicate; // ZSet 是否允许重复元素
public StructRedisCacheManager(
RedisCacheWriter cacheWriter,
RedisCacheConfiguration defaultCacheConfig,
RedisConnectionFactory connectionFactory,
boolean hashAllowOverwrite,
boolean zsetAllowDuplicate
) {
super(cacheWriter, defaultCacheConfig);
this.connectionFactory = connectionFactory;
this.hashAllowOverwrite = hashAllowOverwrite;
this.zsetAllowDuplicate = zsetAllowDuplicate;
}
/**
* 重载构造器(支持自定义缓存配置)
*/
public StructRedisCacheManager(
RedisCacheWriter cacheWriter,
RedisCacheConfiguration defaultCacheConfig,
Map<String, RedisCacheConfiguration> initialCacheConfigurations,
RedisConnectionFactory connectionFactory,
boolean hashAllowOverwrite,
boolean zsetAllowDuplicate
) {
super(cacheWriter, defaultCacheConfig, initialCacheConfigurations);
this.connectionFactory = connectionFactory;
this.hashAllowOverwrite = hashAllowOverwrite;
this.zsetAllowDuplicate = zsetAllowDuplicate;
}
/**
* 核心:根据缓存名选择对应的缓存结构实现
*/
@Override
protected RedisCache createRedisCache(String cacheName, RedisCacheConfiguration config) {
// 解析缓存结构类型
CacheStructType structType = parseStructType(cacheName);
// 提取业务缓存名(去除结构前缀)
String bizName = extractBizName(cacheName, structType);
// 根据类型创建对应缓存实例
switch (structType) {
case HASH:
// 创建 Hash 结构缓存
return new HashRedisCache(
bizName,
getCacheWriter(),
config != null ? config : getDefaultCacheConfiguration(),
connectionFactory,
hashAllowOverwrite
);
case ZSET:
// 创建 ZSet 结构缓存
return new ZSetRedisCache(
bizName,
getCacheWriter(),
config != null ? config : getDefaultCacheConfiguration(),
connectionFactory,
zsetAllowDuplicate
);
default:
// 默认使用普通字符串缓存(Spring 原生实现)
return super.createRedisCache(bizName, config);
}
}
/**
* 解析缓存名对应的结构类型(通过前缀判断)
*/
private CacheStructType parseStructType(String cacheName) {
if (cacheName.startsWith(HASH_PREFIX)) {
return CacheStructType.HASH;
} else if (cacheName.startsWith(ZSET_PREFIX)) {
return CacheStructType.ZSET;
} else {
return CacheStructType.STRING;
}
}
/**
* 提取业务缓存名(去除结构前缀)
*/
private String extractBizName(String cacheName, CacheStructType structType) {
switch (structType) {
case HASH:
return cacheName.substring(HASH_PREFIX.length());
case ZSET:
return cacheName.substring(ZSET_PREFIX.length());
default:
return cacheName;
}
}
}