diff --git a/pom.xml b/pom.xml
index dddeac86c..064cd6ad1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,7 +28,7 @@
3.9.1
5.8.40
3.5.5
- 3.52.0
+ 4.0.0
2.2.7
4.3.1
1.8.0
@@ -261,6 +261,17 @@
org.redisson
redisson-spring-boot-starter
${redisson.version}
+
+
+ org.redisson
+ redisson-spring-data-40
+
+
+
+
+ org.redisson
+ redisson-spring-data-35
+ ${redisson.version}
diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml
index 1b52fab96..30884eeeb 100644
--- a/ruoyi-admin/src/main/resources/application-dev.yml
+++ b/ruoyi-admin/src/main/resources/application-dev.yml
@@ -107,29 +107,28 @@ spring.data:
timeout: 10s
# 是否开启ssl
ssl.enabled: false
-
-# redisson 配置
-redisson:
- # redis key前缀
- keyPrefix:
- # 线程池数量
- threads: 4
- # Netty线程池数量
- nettyThreads: 8
- # 单节点配置
- singleServerConfig:
- # 客户端名称 不能用中文
- clientName: RuoYi-Vue-Plus
- # 最小空闲连接数
- connectionMinimumIdleSize: 8
- # 连接池大小
- connectionPoolSize: 32
- # 连接空闲超时,单位:毫秒
- idleConnectionTimeout: 10000
- # 命令等待超时,单位:毫秒
- timeout: 3000
- # 发布和订阅连接池大小
- subscriptionConnectionPoolSize: 50
+ # redisson 配置 官方文档:https://redisson.pro/docs/integration-with-spring/#spring-boot-starter
+ redisson:
+ # redis key前缀
+ keyPrefix:
+ # 线程池数量
+ threads: 4
+ # Netty线程池数量
+ nettyThreads: 8
+ # 单节点配置
+ singleServerConfig:
+ # 客户端名称 不能用中文
+ clientName: RuoYi-Vue-Plus
+ # 最小空闲连接数
+ connectionMinimumIdleSize: 8
+ # 连接池大小
+ connectionPoolSize: 32
+ # 连接空闲超时,单位:毫秒
+ idleConnectionTimeout: 10000
+ # 命令等待超时,单位:毫秒
+ timeout: 3000
+ # 发布和订阅连接池大小
+ subscriptionConnectionPoolSize: 50
--- # mail 邮件发送
mail:
diff --git a/ruoyi-admin/src/main/resources/application-prod.yml b/ruoyi-admin/src/main/resources/application-prod.yml
index d77ddf57c..057936d5c 100644
--- a/ruoyi-admin/src/main/resources/application-prod.yml
+++ b/ruoyi-admin/src/main/resources/application-prod.yml
@@ -110,29 +110,28 @@ spring.data:
timeout: 10s
# 是否开启ssl
ssl.enabled: false
-
-# redisson 配置
-redisson:
- # redis key前缀
- keyPrefix:
- # 线程池数量
- threads: 16
- # Netty线程池数量
- nettyThreads: 32
- # 单节点配置
- singleServerConfig:
- # 客户端名称 不能用中文
- clientName: RuoYi-Vue-Plus
- # 最小空闲连接数
- connectionMinimumIdleSize: 32
- # 连接池大小
- connectionPoolSize: 64
- # 连接空闲超时,单位:毫秒
- idleConnectionTimeout: 10000
- # 命令等待超时,单位:毫秒
- timeout: 3000
- # 发布和订阅连接池大小
- subscriptionConnectionPoolSize: 50
+ # redisson 配置 官方文档:https://redisson.pro/docs/integration-with-spring/#spring-boot-starter
+ redisson:
+ # redis key前缀
+ keyPrefix:
+ # 线程池数量
+ threads: 16
+ # Netty线程池数量
+ nettyThreads: 32
+ # 单节点配置
+ singleServerConfig:
+ # 客户端名称 不能用中文
+ clientName: RuoYi-Vue-Plus
+ # 最小空闲连接数
+ connectionMinimumIdleSize: 32
+ # 连接池大小
+ connectionPoolSize: 64
+ # 连接空闲超时,单位:毫秒
+ idleConnectionTimeout: 10000
+ # 命令等待超时,单位:毫秒
+ timeout: 3000
+ # 发布和订阅连接池大小
+ subscriptionConnectionPoolSize: 50
--- # mail 邮件发送
mail:
diff --git a/ruoyi-common/ruoyi-common-redis/pom.xml b/ruoyi-common/ruoyi-common-redis/pom.xml
index 576be5e14..b961863b9 100644
--- a/ruoyi-common/ruoyi-common-redis/pom.xml
+++ b/ruoyi-common/ruoyi-common-redis/pom.xml
@@ -27,6 +27,10 @@
org.redisson
redisson-spring-boot-starter
+
+ org.redisson
+ redisson-spring-data-35
+
com.baomidou
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java
index 4c39196e8..1cf6142f2 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/RedisConfig.java
@@ -1,6 +1,5 @@
package org.dromara.common.redis.config;
-import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
@@ -10,16 +9,14 @@ import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.SpringUtils;
-import org.dromara.common.redis.config.properties.RedissonProperties;
import org.dromara.common.redis.handler.KeyPrefixHandler;
import org.dromara.common.redis.handler.RedisExceptionHandler;
import org.redisson.client.codec.StringCodec;
import org.redisson.codec.CompositeCodec;
import org.redisson.codec.TypedJsonJacksonCodec;
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfiguration;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.core.task.VirtualThreadTaskExecutor;
@@ -34,11 +31,13 @@ import java.util.TimeZone;
*/
@Slf4j
@AutoConfiguration
-@EnableConfigurationProperties(RedissonProperties.class)
public class RedisConfig {
- @Autowired
- private RedissonProperties redissonProperties;
+ /**
+ * redis缓存key前缀
+ */
+ @Value("${spring.data.redis.redisson.keyPrefix}")
+ private String keyPrefix;
@Bean
public RedissonAutoConfigurationCustomizer redissonCustomizer() {
@@ -60,44 +59,11 @@ public class RedisConfig {
TypedJsonJacksonCodec jsonCodec = new TypedJsonJacksonCodec(Object.class, om);
// 组合序列化 key 使用 String 内容使用通用 json 格式
CompositeCodec codec = new CompositeCodec(StringCodec.INSTANCE, jsonCodec, jsonCodec);
- config.setThreads(redissonProperties.getThreads())
- .setNettyThreads(redissonProperties.getNettyThreads())
- // 缓存 Lua 脚本 减少网络传输(redisson 大部分的功能都是基于 Lua 脚本实现)
- .setUseScriptCache(true)
- .setCodec(codec);
+ config.setCodec(codec);
if (SpringUtils.isVirtual()) {
config.setNettyExecutor(new VirtualThreadTaskExecutor("redisson-"));
}
- RedissonProperties.SingleServerConfig singleServerConfig = redissonProperties.getSingleServerConfig();
- if (ObjectUtil.isNotNull(singleServerConfig)) {
- // 使用单机模式
- config.useSingleServer()
- //设置redis key前缀
- .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
- .setTimeout(singleServerConfig.getTimeout())
- .setClientName(singleServerConfig.getClientName())
- .setIdleConnectionTimeout(singleServerConfig.getIdleConnectionTimeout())
- .setSubscriptionConnectionPoolSize(singleServerConfig.getSubscriptionConnectionPoolSize())
- .setConnectionMinimumIdleSize(singleServerConfig.getConnectionMinimumIdleSize())
- .setConnectionPoolSize(singleServerConfig.getConnectionPoolSize());
- }
- // 集群配置方式 参考下方注释
- RedissonProperties.ClusterServersConfig clusterServersConfig = redissonProperties.getClusterServersConfig();
- if (ObjectUtil.isNotNull(clusterServersConfig)) {
- config.useClusterServers()
- //设置redis key前缀
- .setNameMapper(new KeyPrefixHandler(redissonProperties.getKeyPrefix()))
- .setTimeout(clusterServersConfig.getTimeout())
- .setClientName(clusterServersConfig.getClientName())
- .setIdleConnectionTimeout(clusterServersConfig.getIdleConnectionTimeout())
- .setSubscriptionConnectionPoolSize(clusterServersConfig.getSubscriptionConnectionPoolSize())
- .setMasterConnectionMinimumIdleSize(clusterServersConfig.getMasterConnectionMinimumIdleSize())
- .setMasterConnectionPoolSize(clusterServersConfig.getMasterConnectionPoolSize())
- .setSlaveConnectionMinimumIdleSize(clusterServersConfig.getSlaveConnectionMinimumIdleSize())
- .setSlaveConnectionPoolSize(clusterServersConfig.getSlaveConnectionPoolSize())
- .setReadMode(clusterServersConfig.getReadMode())
- .setSubscriptionMode(clusterServersConfig.getSubscriptionMode());
- }
+ config.setNameMapper(new KeyPrefixHandler(keyPrefix));
log.info("初始化 redis 配置");
};
}
@@ -127,34 +93,34 @@ public class RedisConfig {
* timeout: 10s
* # 是否开启ssl
* ssl.enabled: false
- *
- * redisson:
- * # 线程池数量
- * threads: 16
- * # Netty线程池数量
- * nettyThreads: 32
- * # 集群配置
- * clusterServersConfig:
- * # 客户端名称
- * clientName: ${ruoyi.name}
- * # master最小空闲连接数
- * masterConnectionMinimumIdleSize: 32
- * # master连接池大小
- * masterConnectionPoolSize: 64
- * # slave最小空闲连接数
- * slaveConnectionMinimumIdleSize: 32
- * # slave连接池大小
- * slaveConnectionPoolSize: 64
- * # 连接空闲超时,单位:毫秒
- * idleConnectionTimeout: 10000
- * # 命令等待超时,单位:毫秒
- * timeout: 3000
- * # 发布和订阅连接池大小
- * subscriptionConnectionPoolSize: 50
- * # 读取模式
- * readMode: "SLAVE"
- * # 订阅模式
- * subscriptionMode: "MASTER"
+ * # redisson配置
+ * redisson:
+ * # 线程池数量
+ * threads: 16
+ * # Netty线程池数量
+ * nettyThreads: 32
+ * # 集群配置
+ * clusterServersConfig:
+ * # 客户端名称
+ * clientName: ${ruoyi.name}
+ * # master最小空闲连接数
+ * masterConnectionMinimumIdleSize: 32
+ * # master连接池大小
+ * masterConnectionPoolSize: 64
+ * # slave最小空闲连接数
+ * slaveConnectionMinimumIdleSize: 32
+ * # slave连接池大小
+ * slaveConnectionPoolSize: 64
+ * # 连接空闲超时,单位:毫秒
+ * idleConnectionTimeout: 10000
+ * # 命令等待超时,单位:毫秒
+ * timeout: 3000
+ * # 发布和订阅连接池大小
+ * subscriptionConnectionPoolSize: 50
+ * # 读取模式
+ * readMode: "SLAVE"
+ * # 订阅模式
+ * subscriptionMode: "MASTER"
*/
}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/properties/RedissonProperties.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/properties/RedissonProperties.java
deleted file mode 100644
index ebec7861a..000000000
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/config/properties/RedissonProperties.java
+++ /dev/null
@@ -1,135 +0,0 @@
-package org.dromara.common.redis.config.properties;
-
-import lombok.Data;
-import lombok.NoArgsConstructor;
-import org.redisson.config.ReadMode;
-import org.redisson.config.SubscriptionMode;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * Redisson 配置属性
- *
- * @author Lion Li
- */
-@Data
-@ConfigurationProperties(prefix = "redisson")
-public class RedissonProperties {
-
- /**
- * redis缓存key前缀
- */
- private String keyPrefix;
-
- /**
- * 线程池数量,默认值 = 当前处理核数量 * 2
- */
- private int threads;
-
- /**
- * Netty线程池数量,默认值 = 当前处理核数量 * 2
- */
- private int nettyThreads;
-
- /**
- * 单机服务配置
- */
- private SingleServerConfig singleServerConfig;
-
- /**
- * 集群服务配置
- */
- private ClusterServersConfig clusterServersConfig;
-
- @Data
- @NoArgsConstructor
- public static class SingleServerConfig {
-
- /**
- * 客户端名称
- */
- private String clientName;
-
- /**
- * 最小空闲连接数
- */
- private int connectionMinimumIdleSize;
-
- /**
- * 连接池大小
- */
- private int connectionPoolSize;
-
- /**
- * 连接空闲超时,单位:毫秒
- */
- private int idleConnectionTimeout;
-
- /**
- * 命令等待超时,单位:毫秒
- */
- private int timeout;
-
- /**
- * 发布和订阅连接池大小
- */
- private int subscriptionConnectionPoolSize;
-
- }
-
- @Data
- @NoArgsConstructor
- public static class ClusterServersConfig {
-
- /**
- * 客户端名称
- */
- private String clientName;
-
- /**
- * master最小空闲连接数
- */
- private int masterConnectionMinimumIdleSize;
-
- /**
- * master连接池大小
- */
- private int masterConnectionPoolSize;
-
- /**
- * slave最小空闲连接数
- */
- private int slaveConnectionMinimumIdleSize;
-
- /**
- * slave连接池大小
- */
- private int slaveConnectionPoolSize;
-
- /**
- * 连接空闲超时,单位:毫秒
- */
- private int idleConnectionTimeout;
-
- /**
- * 命令等待超时,单位:毫秒
- */
- private int timeout;
-
- /**
- * 发布和订阅连接池大小
- */
- private int subscriptionConnectionPoolSize;
-
- /**
- * 读取模式
- */
- private ReadMode readMode;
-
- /**
- * 订阅模式
- */
- private SubscriptionMode subscriptionMode;
-
- }
-
-}
diff --git a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java
index 3bf3e346a..33d5cde82 100644
--- a/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java
+++ b/ruoyi-common/ruoyi-common-redis/src/main/java/org/dromara/common/redis/handler/KeyPrefixHandler.java
@@ -1,7 +1,7 @@
package org.dromara.common.redis.handler;
import org.dromara.common.core.utils.StringUtils;
-import org.redisson.api.NameMapper;
+import org.redisson.config.NameMapper;
/**
* redis缓存key前缀处理
@@ -24,9 +24,6 @@ public class KeyPrefixHandler implements NameMapper {
*/
@Override
public String map(String name) {
- if (StringUtils.isBlank(name)) {
- return null;
- }
if (StringUtils.isNotBlank(keyPrefix) && !name.startsWith(keyPrefix)) {
return keyPrefix + name;
}
@@ -38,9 +35,6 @@ public class KeyPrefixHandler implements NameMapper {
*/
@Override
public String unmap(String name) {
- if (StringUtils.isBlank(name)) {
- return null;
- }
if (StringUtils.isNotBlank(keyPrefix) && name.startsWith(keyPrefix)) {
return name.substring(keyPrefix.length());
}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
index 3767fa2f1..9f25ecfbe 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/config/TenantConfig.java
@@ -1,18 +1,14 @@
package org.dromara.common.tenant.config;
import cn.dev33.satoken.dao.SaTokenDao;
-import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
-import org.dromara.common.core.utils.reflect.ReflectUtils;
import org.dromara.common.redis.config.RedisConfig;
-import org.dromara.common.redis.config.properties.RedissonProperties;
+import org.dromara.common.redis.handler.KeyPrefixHandler;
import org.dromara.common.tenant.core.TenantSaTokenDao;
import org.dromara.common.tenant.handle.PlusTenantLineHandler;
import org.dromara.common.tenant.handle.TenantKeyPrefixHandler;
import org.dromara.common.tenant.manager.TenantSpringCacheManager;
import org.dromara.common.tenant.properties.TenantProperties;
-import org.redisson.config.ClusterServersConfig;
-import org.redisson.config.SingleServerConfig;
import org.redisson.spring.starter.RedissonAutoConfigurationCustomizer;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -47,20 +43,11 @@ public class TenantConfig {
}
@Bean
- public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer(RedissonProperties redissonProperties) {
+ public RedissonAutoConfigurationCustomizer tenantRedissonCustomizer() {
return config -> {
- TenantKeyPrefixHandler nameMapper = new TenantKeyPrefixHandler(redissonProperties.getKeyPrefix());
- SingleServerConfig singleServerConfig = ReflectUtils.invokeGetter(config, "singleServerConfig");
- if (ObjectUtil.isNotNull(singleServerConfig)) {
- // 使用单机模式
- // 设置多租户 redis key前缀
- singleServerConfig.setNameMapper(nameMapper);
- }
- ClusterServersConfig clusterServersConfig = ReflectUtils.invokeGetter(config, "clusterServersConfig");
- // 集群配置方式 参考下方注释
- if (ObjectUtil.isNotNull(clusterServersConfig)) {
- // 设置多租户 redis key前缀
- clusterServersConfig.setNameMapper(nameMapper);
+ if (config.getNameMapper() instanceof KeyPrefixHandler handler) {
+ // 使用多租户redis缓存key前缀处理器
+ config.setNameMapper(new TenantKeyPrefixHandler(handler));
}
};
}
diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/TenantKeyPrefixHandler.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/TenantKeyPrefixHandler.java
index dcdef6e62..bcac4675c 100644
--- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/TenantKeyPrefixHandler.java
+++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/handle/TenantKeyPrefixHandler.java
@@ -6,6 +6,7 @@ import org.dromara.common.core.constant.GlobalConstants;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.redis.handler.KeyPrefixHandler;
import org.dromara.common.tenant.helper.TenantHelper;
+import org.redisson.config.NameMapper;
/**
* 多租户redis缓存key前缀处理
@@ -13,10 +14,15 @@ import org.dromara.common.tenant.helper.TenantHelper;
* @author Lion Li
*/
@Slf4j
-public class TenantKeyPrefixHandler extends KeyPrefixHandler {
+public class TenantKeyPrefixHandler implements NameMapper {
- public TenantKeyPrefixHandler(String keyPrefix) {
- super(keyPrefix);
+ /**
+ * Key前缀处理器
+ */
+ private final KeyPrefixHandler handler;
+
+ public TenantKeyPrefixHandler(KeyPrefixHandler handler) {
+ this.handler = handler;
}
/**
@@ -25,28 +31,24 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
@Override
public String map(String name) {
if (StringUtils.isBlank(name)) {
- return null;
+ return name;
}
- try {
- if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) {
- return super.map(name);
- }
- } catch (NoClassDefFoundError ignore) {
- // 有些服务不需要mp导致类不存在 忽略即可
- }
- if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
- return super.map(name);
+ // 租户忽略和全局键检查
+ if (shouldSkipTenantProcessing() || StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
+ return handler.map(name);
}
+ // 拼接租户前缀
String tenantId = TenantHelper.getTenantId();
if (StringUtils.isBlank(tenantId)) {
log.debug("无法获取有效的租户id -> Null");
- return super.map(name);
+ return handler.map(name);
}
- if (StringUtils.startsWith(name, tenantId + "")) {
+ String tenantPrefix = tenantId + ":";
+ if (StringUtils.startsWith(name, tenantPrefix)) {
// 如果存在则直接返回
- return super.map(name);
+ return handler.map(name);
}
- return super.map(tenantId + ":" + name);
+ return handler.map(tenantPrefix + name);
}
/**
@@ -54,30 +56,35 @@ public class TenantKeyPrefixHandler extends KeyPrefixHandler {
*/
@Override
public String unmap(String name) {
- String unmap = super.unmap(name);
+ String unmap = handler.unmap(name);
if (StringUtils.isBlank(unmap)) {
- return null;
- }
- try {
- if (InterceptorIgnoreHelper.willIgnoreTenantLine("")) {
- return unmap;
- }
- } catch (NoClassDefFoundError ignore) {
- // 有些服务不需要mp导致类不存在 忽略即可
- }
- if (StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
return unmap;
}
+ // 租户忽略和全局键检查
+ if (shouldSkipTenantProcessing() || StringUtils.contains(name, GlobalConstants.GLOBAL_REDIS_KEY)) {
+ return unmap;
+ }
+ // 拼接租户前缀
String tenantId = TenantHelper.getTenantId();
if (StringUtils.isBlank(tenantId)) {
log.debug("无法获取有效的租户id -> Null");
return unmap;
}
- if (StringUtils.startsWith(unmap, tenantId + "")) {
+ String tenantPrefix = tenantId + ":";
+ if (StringUtils.startsWith(unmap, tenantPrefix)) {
// 如果存在则删除
- return unmap.substring((tenantId + ":").length());
+ return unmap.substring(tenantPrefix.length());
}
return unmap;
}
+ private boolean shouldSkipTenantProcessing() {
+ try {
+ return InterceptorIgnoreHelper.willIgnoreTenantLine("");
+ } catch (NoClassDefFoundError ignore) {
+ // 有些服务不需要mp导致类不存在 忽略即可
+ return false;
+ }
+ }
+
}