spring cache 支持多结构的 Redis 缓存管理器
需求背景: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;}/*** 核心:根据缓存名选择对应的缓存结构实现*/@Overrideprotected 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;}}
}