彻底移除 RedisKeyDefine

pull/46/head
YunaiV 2023-07-29 07:16:16 +08:00
parent 8b704ff483
commit 0b17298963
16 changed files with 43 additions and 368 deletions

View File

@ -1,47 +0,0 @@
package cn.iocoder.yudao.framework.tenant.core.redis;
import cn.hutool.core.util.ArrayUtil;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import java.time.Duration;
/**
* RedisKeyDefine
*
* Redis MySQL column WHERE tenant_id = ?
* Redis Key
* 1. Redis Key user:%d user:1 Redis Key user:%d:%d
* 2. Redis DAO 使 {@link #formatKey(Object...)} Redis Key
*
* 使 TenantRedisKeyDefine 使 Redis Key
* 1 2 Key
*
* @author
*/
public class TenantRedisKeyDefine extends RedisKeyDefine {
/**
* KEY
*/
private static final String KEY_TEMPLATE_SUFFIX = ":%d";
public TenantRedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, Duration timeout) {
super(memo, buildKeyTemplate(keyTemplate), keyType, valueType, timeout);
}
public TenantRedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, TimeoutTypeEnum timeoutType) {
super(memo, buildKeyTemplate(keyTemplate), keyType, valueType, timeoutType);
}
private static String buildKeyTemplate(String keyTemplate) {
return keyTemplate + KEY_TEMPLATE_SUFFIX;
}
@Override
public String formatKey(Object... args) {
args = ArrayUtil.append(args, TenantContextHolder.getRequiredTenantId());
return super.formatKey(args);
}
}

View File

@ -1,27 +0,0 @@
package cn.iocoder.yudao.framework.tenant.core.redis;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class TenantRedisKeyDefineTest {
@Test
public void testFormatKey() {
Long tenantId = 30L;
TenantContextHolder.setTenantId(tenantId);
// 准备参数
TenantRedisKeyDefine define = new TenantRedisKeyDefine("", "user:%d:%d", RedisKeyDefine.KeyTypeEnum.HASH,
Object.class, RedisKeyDefine.TimeoutTypeEnum.FIXED);
Long userId = 10L;
Integer userType = 1;
// 调用
String key = define.formatKey(userId, userType);
// 断言
assertEquals("user:10:1:30", key);
}
}

View File

@ -1,7 +1,5 @@
package cn.iocoder.yudao.framework.captcha.config; package cn.iocoder.yudao.framework.captcha.config;
import cn.hutool.core.util.ClassUtil;
import cn.iocoder.yudao.framework.captcha.core.enums.CaptchaRedisKeyConstants;
import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl; import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl;
import com.xingyuv.captcha.properties.AjCaptchaProperties; import com.xingyuv.captcha.properties.AjCaptchaProperties;
import com.xingyuv.captcha.service.CaptchaCacheService; import com.xingyuv.captcha.service.CaptchaCacheService;
@ -15,12 +13,6 @@ import javax.annotation.Resource;
@AutoConfiguration @AutoConfiguration
public class YudaoCaptchaConfiguration { public class YudaoCaptchaConfiguration {
static {
// 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到
// 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举
ClassUtil.loadClass(CaptchaRedisKeyConstants.class.getName());
}
@Resource @Resource
private StringRedisTemplate stringRedisTemplate; private StringRedisTemplate stringRedisTemplate;

View File

@ -1,12 +1,5 @@
package cn.iocoder.yudao.framework.captcha.core.enums; package cn.iocoder.yudao.framework.captcha.core.enums;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import com.xingyuv.captcha.model.vo.PointVO;
import java.time.Duration;
import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.STRING;
/** /**
* Redis Key * Redis Key
* *
@ -14,12 +7,22 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S
*/ */
public interface CaptchaRedisKeyConstants { public interface CaptchaRedisKeyConstants {
RedisKeyDefine AJ_CAPTCHA_REQ_LIMIT = new RedisKeyDefine("验证码的请求限流", /**
"AJ.CAPTCHA.REQ.LIMIT-%s-%s", *
STRING, Integer.class, Duration.ofSeconds(60)); // 例如说:验证失败 5 次get 接口锁定 *
* KEY AJ.CAPTCHA.REQ.LIMIT-%s-%s
* VALUE String // 例如说:验证失败 5 次get 接口锁定
* 60
*/
String AJ_CAPTCHA_REQ_LIMIT = "AJ.CAPTCHA.REQ.LIMIT-%s-%s";
RedisKeyDefine AJ_CAPTCHA_RUNNING = new RedisKeyDefine("验证码的坐标", /**
"RUNNING:CAPTCHA:%s", // AbstractCaptchaService.REDIS_CAPTCHA_KEY *
STRING, PointVO.class, Duration.ofSeconds(120)); // {"secretKey":"PP1w2Frr2KEejD2m","x":162,"y":5} *
* KEY RUNNING:CAPTCHA:%s // AbstractCaptchaService.REDIS_CAPTCHA_KEY
* VALUE String // PointVO.class {"secretKey":"PP1w2Frr2KEejD2m","x":162,"y":5}
* 120
*/
String AJ_CAPTCHA_RUNNING = "RUNNING:CAPTCHA:%s";
} }

View File

@ -1,13 +1,10 @@
package cn.iocoder.yudao.framework.idempotent.core.redis; package cn.iocoder.yudao.framework.idempotent.core.redis;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.STRING;
/** /**
* Redis DAO * Redis DAO
* *
@ -16,9 +13,14 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S
@AllArgsConstructor @AllArgsConstructor
public class IdempotentRedisDAO { public class IdempotentRedisDAO {
private static final RedisKeyDefine IDEMPOTENT = new RedisKeyDefine("幂等操作", /**
"idempotent:%s", // 参数为 uuid *
STRING, String.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); *
* KEY idempotent:%s // 参数为 uuid
* VALUE String
*
*/
private static final String IDEMPOTENT = "idempotent:%s";
private final StringRedisTemplate redisTemplate; private final StringRedisTemplate redisTemplate;
@ -28,7 +30,7 @@ public class IdempotentRedisDAO {
} }
private static String formatKey(String key) { private static String formatKey(String key) {
return String.format(IDEMPOTENT.getKeyTemplate(), key); return String.format(IDEMPOTENT, key);
} }
} }

View File

@ -1,21 +1,13 @@
package cn.iocoder.yudao.framework.lock4j.config; package cn.iocoder.yudao.framework.lock4j.config;
import cn.hutool.core.util.ClassUtil;
import com.baomidou.lock.spring.boot.autoconfigure.LockAutoConfiguration;
import cn.iocoder.yudao.framework.lock4j.core.DefaultLockFailureStrategy; import cn.iocoder.yudao.framework.lock4j.core.DefaultLockFailureStrategy;
import cn.iocoder.yudao.framework.lock4j.core.Lock4jRedisKeyConstants; import com.baomidou.lock.spring.boot.autoconfigure.LockAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
@AutoConfiguration(before = LockAutoConfiguration.class) @AutoConfiguration(before = LockAutoConfiguration.class)
public class YudaoLock4jConfiguration { public class YudaoLock4jConfiguration {
static {
// 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到
// 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举
ClassUtil.loadClass(Lock4jRedisKeyConstants.class.getName());
}
@Bean @Bean
public DefaultLockFailureStrategy lockFailureStrategy() { public DefaultLockFailureStrategy lockFailureStrategy() {
return new DefaultLockFailureStrategy(); return new DefaultLockFailureStrategy();

View File

@ -1,10 +1,5 @@
package cn.iocoder.yudao.framework.lock4j.core; package cn.iocoder.yudao.framework.lock4j.core;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import org.redisson.api.RLock;
import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.HASH;
/** /**
* Lock4j Redis Key * Lock4j Redis Key
* *
@ -12,8 +7,13 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.H
*/ */
public interface Lock4jRedisKeyConstants { public interface Lock4jRedisKeyConstants {
RedisKeyDefine LOCK4J = new RedisKeyDefine("分布式锁", /**
"lock4j:%s", // 参数来自 DefaultLockKeyBuilder 类 *
HASH, RLock.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); // Redisson 的 Lock 锁,使用 Hash 数据结构 *
* KEY lock4j:%s // 参数来自 DefaultLockKeyBuilder 类
* VALUE HASH // RLock.classRedisson 的 Lock 锁,使用 Hash 数据结构
*
*/
String LOCK4J = "lock4j:%s";
} }

View File

@ -1,113 +0,0 @@
package cn.iocoder.yudao.framework.redis.core;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import java.time.Duration;
/**
* Redis Key
*
* @author
*/
@Data
public class RedisKeyDefine {
@Getter
@AllArgsConstructor
public enum KeyTypeEnum {
STRING("String"),
LIST("List"),
HASH("Hash"),
SET("Set"),
ZSET("Sorted Set"),
STREAM("Stream"),
PUBSUB("Pub/Sub");
/**
*
*/
@JsonValue
private final String type;
}
@Getter
@AllArgsConstructor
public enum TimeoutTypeEnum {
FOREVER(1), // 永不超时
DYNAMIC(2), // 动态超时
FIXED(3); // 固定超时
/**
*
*/
@JsonValue
private final Integer type;
}
/**
* Key
*/
private final String keyTemplate;
/**
* Key
*/
private final KeyTypeEnum keyType;
/**
* Value
*
* 使 {@link java.util.concurrent.locks.Lock}
*/
private final Class<?> valueType;
/**
*
*/
private final TimeoutTypeEnum timeoutType;
/**
*
*/
private final Duration timeout;
/**
*
*/
private final String memo;
private RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType,
TimeoutTypeEnum timeoutType, Duration timeout) {
this.memo = memo;
this.keyTemplate = keyTemplate;
this.keyType = keyType;
this.valueType = valueType;
this.timeout = timeout;
this.timeoutType = timeoutType;
// 添加注册表
RedisKeyRegistry.add(this);
}
public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, Duration timeout) {
this(memo, keyTemplate, keyType, valueType, TimeoutTypeEnum.FIXED, timeout);
}
public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, TimeoutTypeEnum timeoutType) {
this(memo, keyTemplate, keyType, valueType, timeoutType, Duration.ZERO);
}
/**
* Key
*
* {@link String#format(String, Object...)}
*
* @param args
* @return Key
*/
public String formatKey(Object... args) {
return String.format(keyTemplate, args);
}
}

View File

@ -1,28 +0,0 @@
package cn.iocoder.yudao.framework.redis.core;
import java.util.ArrayList;
import java.util.List;
/**
* {@link RedisKeyDefine}
*/
public class RedisKeyRegistry {
/**
* Redis RedisKeyDefine
*/
private static final List<RedisKeyDefine> DEFINES = new ArrayList<>();
public static void add(RedisKeyDefine define) {
DEFINES.add(define);
}
public static List<RedisKeyDefine> list() {
return DEFINES;
}
public static int size() {
return DEFINES.size();
}
}

View File

@ -2,8 +2,3 @@
GET {{baseUrl}}/infra/redis/get-monitor-info GET {{baseUrl}}/infra/redis/get-monitor-info
Authorization: Bearer {{token}} Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}} tenant-id: {{adminTenentId}}
### 请求 /infra/redis/get-key-list 接口 => 成功
GET {{baseUrl}}/infra/redis/get-key-list
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}

View File

@ -1,36 +0,0 @@
package cn.iocoder.yudao.module.infra.controller.admin.redis.vo;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import java.time.Duration;
@Schema(description = "管理后台 - Redis Key 信息 Response VO")
@Data
@Builder
@AllArgsConstructor
public class RedisKeyDefineRespVO {
@Schema(description = "Key 模板", requiredMode = Schema.RequiredMode.REQUIRED, example = "login_user:%s")
private String keyTemplate;
@Schema(description = "Key 类型的枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
private RedisKeyDefine.KeyTypeEnum keyType;
@Schema(description = "Value 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "java.lang.String")
private Class<?> valueType;
@Schema(description = "超时类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private RedisKeyDefine.TimeoutTypeEnum timeoutType;
@Schema(description = "过期时间,单位:毫秒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Duration timeout;
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "啦啦啦啦~")
private String memo;
}

View File

@ -1,36 +0,0 @@
package cn.iocoder.yudao.module.infra.controller.admin.redis.vo;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import java.time.Duration;
@Schema(description = "管理后台 - Redis Key 信息 Response VO")
@Data
@Builder
@AllArgsConstructor
public class RedisKeyRespVO {
@Schema(description = "login_user:%s", requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
private String keyTemplate;
@Schema(description = "Key 类型的枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
private RedisKeyDefine.KeyTypeEnum keyType;
@Schema(description = "Value 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "java.lang.String")
private Class<?> valueType;
@Schema(description = "超时类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private RedisKeyDefine.TimeoutTypeEnum timeoutType;
@Schema(description = "过期时间,单位:毫秒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Duration timeout;
@Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "啦啦啦啦~")
private String memo;
}

View File

@ -1,19 +0,0 @@
package cn.iocoder.yudao.module.infra.controller.admin.redis.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
@Schema(description = "管理后台 - 单个 Redis Key Value Response VO")
@Data
@AllArgsConstructor
public class RedisKeyValueRespVO {
@Schema(description = "c5f6990767804a928f4bb96ca249febf", requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
private String key;
@Schema(requiredMode = Schema.RequiredMode.REQUIRED, example = "String")
private String value;
}

View File

@ -1,14 +1,11 @@
package cn.iocoder.yudao.module.infra.convert.redis; package cn.iocoder.yudao.module.infra.convert.redis;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyDefineRespVO;
import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO; import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.Properties; import java.util.Properties;
@Mapper @Mapper
@ -29,6 +26,4 @@ public interface RedisConvert {
return respVO; return respVO;
} }
List<RedisKeyDefineRespVO> convertList(List<RedisKeyDefine> list);
} }

View File

@ -1,8 +1,5 @@
package cn.iocoder.yudao.module.pay.dal.redis; package cn.iocoder.yudao.module.pay.dal.redis;
import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine;
import org.redisson.api.RLock;
/** /**
* Redis Key * Redis Key
* *
@ -10,9 +7,14 @@ import org.redisson.api.RLock;
*/ */
public interface RedisKeyConstants { public interface RedisKeyConstants {
RedisKeyDefine PAY_NOTIFY_LOCK = new RedisKeyDefine("通知任务的分布式锁", /**
"pay_notify:lock:%d", // 参数来自 DefaultLockKeyBuilder 类 *
RedisKeyDefine.KeyTypeEnum.HASH, RLock.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); // Redisson 的 Lock 锁,使用 Hash 数据结构 *
* KEY pay_notify:lock:%d // 参数来自 DefaultLockKeyBuilder 类
* VALUE HASH // RLock.classRedisson 的 Lock 锁,使用 Hash 数据结构
*
*/
String PAY_NOTIFY_LOCK = "pay_notify:lock:%d";
/** /**
* *

View File

@ -33,7 +33,7 @@ public class PayNotifyLockRedisDAO {
} }
private static String formatKey(Long id) { private static String formatKey(Long id) {
return String.format(PAY_NOTIFY_LOCK.getKeyTemplate(), id); return String.format(PAY_NOTIFY_LOCK, id);
} }
} }