From e9bfa1396ff47d171b3052a606e0931e6f93cc9c Mon Sep 17 00:00:00 2001 From: houzhongjian <houzhongyi@126.com> Date: 星期四, 10 四月 2025 12:05:23 +0800 Subject: [PATCH] 还原framework代码 --- iailab-framework/iailab-common-redis/src/main/java/com/iailab/framework/redis/core/TimeoutRedisCacheManager.java | 86 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 86 insertions(+), 0 deletions(-) diff --git a/iailab-framework/iailab-common-redis/src/main/java/com/iailab/framework/redis/core/TimeoutRedisCacheManager.java b/iailab-framework/iailab-common-redis/src/main/java/com/iailab/framework/redis/core/TimeoutRedisCacheManager.java new file mode 100644 index 0000000..de86678 --- /dev/null +++ b/iailab-framework/iailab-common-redis/src/main/java/com/iailab/framework/redis/core/TimeoutRedisCacheManager.java @@ -0,0 +1,86 @@ +package com.iailab.framework.redis.core; + +import cn.hutool.core.util.NumberUtil; +import cn.hutool.core.util.StrUtil; +import org.springframework.cache.annotation.Cacheable; +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 java.time.Duration; + +/** + * 支持自定义过期时间的 {@link RedisCacheManager} 实现类 + * + * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间。 + * 单位为最后一个字母(支持的单位有:d 天,h 小时,m 分钟,s 秒),默认单位为 s 秒 + * + * @author iailab + */ +public class TimeoutRedisCacheManager extends RedisCacheManager { + + private static final String SPLIT = "#"; + + public TimeoutRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) { + super(cacheWriter, defaultCacheConfiguration); + } + + @Override + protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) { + if (StrUtil.isEmpty(name)) { + return super.createRedisCache(name, cacheConfig); + } + // 如果使用 # 分隔,大小不为 2,则说明不使用自定义过期时间 + String[] names = StrUtil.splitToArray(name, SPLIT); + if (names.length != 2) { + return super.createRedisCache(name, cacheConfig); + } + + // 核心:通过修改 cacheConfig 的过期时间,实现自定义过期时间 + if (cacheConfig != null) { + // 移除 # 后面的 : 以及后面的内容,避免影响解析 + String ttlStr = StrUtil.subBefore(names[1], StrUtil.COLON, false); // 获得 ttlStr 时间部分 + names[1] = StrUtil.subAfter(names[1], ttlStr, false); // 移除掉 ttlStr 时间部分 + // 解析时间 + Duration duration = parseDuration(ttlStr); + cacheConfig = cacheConfig.entryTtl(duration); + } + + // 创建 RedisCache 对象,需要忽略掉 ttlStr + return super.createRedisCache(names[0] + names[1], cacheConfig); + } + + /** + * 解析过期时间 Duration + * + * @param ttlStr 过期时间字符串 + * @return 过期时间 Duration + */ + private Duration parseDuration(String ttlStr) { + String timeUnit = StrUtil.subSuf(ttlStr, -1); + switch (timeUnit) { + case "d": + return Duration.ofDays(removeDurationSuffix(ttlStr)); + case "h": + return Duration.ofHours(removeDurationSuffix(ttlStr)); + case "m": + return Duration.ofMinutes(removeDurationSuffix(ttlStr)); + case "s": + return Duration.ofSeconds(removeDurationSuffix(ttlStr)); + default: + return Duration.ofSeconds(Long.parseLong(ttlStr)); + } + } + + /** + * 移除多余的后缀,返回具体的时间 + * + * @param ttlStr 过期时间字符串 + * @return 时间 + */ + private Long removeDurationSuffix(String ttlStr) { + return NumberUtil.parseLong(StrUtil.sub(ttlStr, 0, ttlStr.length() - 1)); + } + +} -- Gitblit v1.9.3