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)); + } + }