diff --git a/pom.xml b/pom.xml
index b602f6a0e..cb84441d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,7 +35,7 @@
3.8.1
1.18.28
- 2.7.13
+ 2.7.14
1.5.5.Final
UTF-8
diff --git a/yudao-dependencies/pom.xml b/yudao-dependencies/pom.xml
index f1d426ae3..17e1cb508 100644
--- a/yudao-dependencies/pom.xml
+++ b/yudao-dependencies/pom.xml
@@ -16,7 +16,7 @@
1.8.0-snapshot
- 2.7.13
+ 2.7.14
2021.0.5
2021.0.4.0
@@ -51,7 +51,7 @@
6.8.0
- 1.0.5
+ 1.0.6
1.15.4
1.18.28
1.5.5.Final
diff --git a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
index fe9adca83..31ec865b0 100644
--- a/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/config/YudaoTenantAutoConfiguration.java
@@ -2,11 +2,10 @@ package cn.iocoder.yudao.framework.tenant.config;
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
+import cn.iocoder.yudao.framework.redis.config.YudaoCacheProperties;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnoreAspect;
import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJobAspect;
-import cn.iocoder.yudao.framework.tenant.core.mq.TenantChannelInterceptor;
-import cn.iocoder.yudao.framework.tenant.core.mq.TenantFunctionAroundWrapper;
import cn.iocoder.yudao.framework.tenant.core.redis.TenantRedisCacheManager;
import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter;
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
@@ -17,24 +16,19 @@ import cn.iocoder.yudao.framework.web.core.handler.GlobalExceptionHandler;
import cn.iocoder.yudao.module.system.api.tenant.TenantApi;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
-import com.xxl.job.core.executor.XxlJobExecutor;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.cloud.function.context.catalog.FunctionAroundWrapper;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
+import org.springframework.data.redis.cache.BatchStrategies;
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 org.springframework.data.redis.core.RedisTemplate;
-import org.springframework.integration.config.GlobalChannelInterceptor;
import java.util.Objects;
@@ -104,12 +98,13 @@ public class YudaoTenantAutoConfiguration {
@Bean
@Primary // 引入租户时,tenantRedisCacheManager 为主 Bean
public RedisCacheManager tenantRedisCacheManager(RedisTemplate redisTemplate,
- RedisCacheConfiguration redisCacheConfiguration) {
+ RedisCacheConfiguration redisCacheConfiguration,
+ YudaoCacheProperties yudaoCacheProperties) {
// 创建 RedisCacheWriter 对象
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
- RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
+ RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
+ BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
// 创建 TenantRedisCacheManager 对象
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration);
}
-
}
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
index 1442e8a83..ad6ef439f 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheAutoConfiguration.java
@@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguratio
* Cache 配置类,基于 Redis 实现
*/
@AutoConfiguration
-@EnableConfigurationProperties({CacheProperties.class})
+@EnableConfigurationProperties({CacheProperties.class, YudaoCacheProperties.class})
@EnableCaching
public class YudaoCacheAutoConfiguration {
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
new file mode 100644
index 000000000..c51219d0f
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/config/YudaoCacheProperties.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.framework.redis.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.validation.annotation.Validated;
+
+/**
+ * Cache 配置项
+ *
+ * @author Wanwan
+ */
+@ConfigurationProperties("yudao.cache")
+@Data
+@Validated
+public class YudaoCacheProperties {
+
+ /**
+ * {@link #redisScanBatchSize} 默认值
+ */
+ private static final Integer REDIS_SCAN_BATCH_SIZE_DEFAULT = 30;
+
+ /**
+ * redis scan 一次返回数量
+ */
+ private Integer redisScanBatchSize = REDIS_SCAN_BATCH_SIZE_DEFAULT;
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
index cfdee653d..bf34fc081 100644
--- a/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
+++ b/yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/TimeoutRedisCacheManager.java
@@ -1,7 +1,7 @@
package cn.iocoder.yudao.framework.redis.core;
+import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
-import org.springframework.boot.convert.DurationStyle;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
@@ -9,12 +9,12 @@ import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import java.time.Duration;
-import java.time.temporal.ChronoUnit;
/**
* 支持自定义过期时间的 {@link RedisCacheManager} 实现类
*
- * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为秒
+ * 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间。
+ * 单位为最后一个字母(支持的单位有:d 天,h 小时,m 分钟,s 秒),默认单位为 s 秒
*
* @author 芋道源码
*/
@@ -42,10 +42,42 @@ public class TimeoutRedisCacheManager extends RedisCacheManager {
// 移除 # 后面的 : 以及后面的内容,避免影响解析
names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false);
// 解析时间
- Duration duration = DurationStyle.detectAndParse(names[1], ChronoUnit.SECONDS);
+ Duration duration = parseDuration(names[1]);
cacheConfig = cacheConfig.entryTtl(duration);
}
return super.createRedisCache(names[0], 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));
+ }
+
}