!562 优化 redisCache
parent
2201a3ad0f
commit
c28ef89a78
2
pom.xml
2
pom.xml
|
@ -35,7 +35,7 @@
|
||||||
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
|
||||||
<!-- 看看咋放到 bom 里 -->
|
<!-- 看看咋放到 bom 里 -->
|
||||||
<lombok.version>1.18.28</lombok.version>
|
<lombok.version>1.18.28</lombok.version>
|
||||||
<spring.boot.version>2.7.13</spring.boot.version>
|
<spring.boot.version>2.7.14</spring.boot.version>
|
||||||
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<properties>
|
<properties>
|
||||||
<revision>1.8.0-snapshot</revision>
|
<revision>1.8.0-snapshot</revision>
|
||||||
<!-- 统一依赖管理 -->
|
<!-- 统一依赖管理 -->
|
||||||
<spring.boot.version>2.7.13</spring.boot.version>
|
<spring.boot.version>2.7.14</spring.boot.version>
|
||||||
<spring.cloud.version>2021.0.5</spring.cloud.version>
|
<spring.cloud.version>2021.0.5</spring.cloud.version>
|
||||||
<spring.cloud.alibaba.version>2021.0.4.0</spring.cloud.alibaba.version>
|
<spring.cloud.alibaba.version>2021.0.4.0</spring.cloud.alibaba.version>
|
||||||
<!-- Web 相关 -->
|
<!-- Web 相关 -->
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
<!-- Bpm 工作流相关 -->
|
<!-- Bpm 工作流相关 -->
|
||||||
<flowable.version>6.8.0</flowable.version>
|
<flowable.version>6.8.0</flowable.version>
|
||||||
<!-- 工具类相关 -->
|
<!-- 工具类相关 -->
|
||||||
<captcha-plus.version>1.0.5</captcha-plus.version>
|
<captcha-plus.version>1.0.6</captcha-plus.version>
|
||||||
<jsoup.version>1.15.4</jsoup.version>
|
<jsoup.version>1.15.4</jsoup.version>
|
||||||
<lombok.version>1.18.28</lombok.version>
|
<lombok.version>1.18.28</lombok.version>
|
||||||
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
<mapstruct.version>1.5.5.Final</mapstruct.version>
|
||||||
|
|
|
@ -2,11 +2,10 @@ package cn.iocoder.yudao.framework.tenant.config;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
|
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.aop.TenantIgnoreAspect;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.db.TenantDatabaseInterceptor;
|
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.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.redis.TenantRedisCacheManager;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter;
|
import cn.iocoder.yudao.framework.tenant.core.security.TenantSecurityWebFilter;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.service.TenantFrameworkService;
|
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 cn.iocoder.yudao.module.system.api.tenant.TenantApi;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
|
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.AutoConfiguration;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
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.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Primary;
|
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.RedisCacheConfiguration;
|
||||||
import org.springframework.data.redis.cache.RedisCacheManager;
|
import org.springframework.data.redis.cache.RedisCacheManager;
|
||||||
import org.springframework.data.redis.cache.RedisCacheWriter;
|
import org.springframework.data.redis.cache.RedisCacheWriter;
|
||||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.integration.config.GlobalChannelInterceptor;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@ -104,12 +98,13 @@ public class YudaoTenantAutoConfiguration {
|
||||||
@Bean
|
@Bean
|
||||||
@Primary // 引入租户时,tenantRedisCacheManager 为主 Bean
|
@Primary // 引入租户时,tenantRedisCacheManager 为主 Bean
|
||||||
public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate,
|
public RedisCacheManager tenantRedisCacheManager(RedisTemplate<String, Object> redisTemplate,
|
||||||
RedisCacheConfiguration redisCacheConfiguration) {
|
RedisCacheConfiguration redisCacheConfiguration,
|
||||||
|
YudaoCacheProperties yudaoCacheProperties) {
|
||||||
// 创建 RedisCacheWriter 对象
|
// 创建 RedisCacheWriter 对象
|
||||||
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
|
RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());
|
||||||
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);
|
RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,
|
||||||
|
BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));
|
||||||
// 创建 TenantRedisCacheManager 对象
|
// 创建 TenantRedisCacheManager 对象
|
||||||
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration);
|
return new TenantRedisCacheManager(cacheWriter, redisCacheConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ import static cn.iocoder.yudao.framework.redis.config.YudaoRedisAutoConfiguratio
|
||||||
* Cache 配置类,基于 Redis 实现
|
* Cache 配置类,基于 Redis 实现
|
||||||
*/
|
*/
|
||||||
@AutoConfiguration
|
@AutoConfiguration
|
||||||
@EnableConfigurationProperties({CacheProperties.class})
|
@EnableConfigurationProperties({CacheProperties.class, YudaoCacheProperties.class})
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
public class YudaoCacheAutoConfiguration {
|
public class YudaoCacheAutoConfiguration {
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package cn.iocoder.yudao.framework.redis.core;
|
package cn.iocoder.yudao.framework.redis.core;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import org.springframework.boot.convert.DurationStyle;
|
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.data.redis.cache.RedisCache;
|
import org.springframework.data.redis.cache.RedisCache;
|
||||||
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
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 org.springframework.data.redis.cache.RedisCacheWriter;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.temporal.ChronoUnit;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支持自定义过期时间的 {@link RedisCacheManager} 实现类
|
* 支持自定义过期时间的 {@link RedisCacheManager} 实现类
|
||||||
*
|
*
|
||||||
* 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间,单位为秒
|
* 在 {@link Cacheable#cacheNames()} 格式为 "key#ttl" 时,# 后面的 ttl 为过期时间。
|
||||||
|
* 单位为最后一个字母(支持的单位有:d 天,h 小时,m 分钟,s 秒),默认单位为 s 秒
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@ -42,10 +42,42 @@ public class TimeoutRedisCacheManager extends RedisCacheManager {
|
||||||
// 移除 # 后面的 : 以及后面的内容,避免影响解析
|
// 移除 # 后面的 : 以及后面的内容,避免影响解析
|
||||||
names[1] = StrUtil.subBefore(names[1], StrUtil.COLON, false);
|
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);
|
cacheConfig = cacheConfig.entryTtl(duration);
|
||||||
}
|
}
|
||||||
return super.createRedisCache(names[0], cacheConfig);
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue