SpringCache、Redis实现指定过期时间

8 篇文章 0 订阅

我们都知道springCache定义了缓存规范,其中redis的解决方案并不支持每个缓存key独自设置过期时间,本方案通过定义cacheName为特定格式,从而设置缓存过期时间。支持设置过期时间单位(默认秒)

1、重写RedisCacheManager的createRedisCache方法。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;

import java.time.Duration;
import java.util.Map;

/**
 * @author Tzx
 * @date 2022/12/13 19:33
 */
public class TaRedisCacheManager extends RedisCacheManager {

    private static final Logger LOGGER = LoggerFactory.getLogger(TaRedisCacheManager.class);

    public TaRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
        super(cacheWriter, defaultCacheConfiguration);
    }

    public TaRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, String... initialCacheNames) {
        super(cacheWriter, defaultCacheConfiguration, initialCacheNames);
    }

    public TaRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, boolean allowInFlightCacheCreation, String... initialCacheNames) {
        super(cacheWriter, defaultCacheConfiguration, allowInFlightCacheCreation, initialCacheNames);
    }

    public TaRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, Map<String, RedisCacheConfiguration> initialCacheConfigurations) {
        super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations);
    }

    public TaRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, Map<String, RedisCacheConfiguration> initialCacheConfigurations, boolean allowInFlightCacheCreation) {
        super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations, allowInFlightCacheCreation);
    }

    @Override
    protected RedisCache createRedisCache(String name, @Nullable RedisCacheConfiguration cacheConfig) {
        String[] params = name.split("#");
        String cacheName = params[0];
        if (params.length > 1) {
            cacheConfig = this.entryTtl(cacheName, params[1], cacheConfig);
        }

        return super.createRedisCache(cacheName, cacheConfig);
    }

    private RedisCacheConfiguration entryTtl(String cacheName, String ttlStr, @Nullable RedisCacheConfiguration cacheConfig) {
        Assert.notNull(cacheConfig, "RedisCacheConfiguration is required; it must not be null");
        // 根据传参设置缓存失效时间
        Duration duration = parseDuration(ttlStr);
        cacheConfig = cacheConfig.entryTtl(duration);
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug("redisCache {} 过期时间为{}秒", cacheName, duration.getSeconds());
        }
        return cacheConfig;
    }

    private Duration parseDuration(String ttlStr) {
        String timeUnit = ttlStr.substring(ttlStr.length() - 1);
        switch (timeUnit) {
            case "d":
                return Duration.ofDays(parseLong(ttlStr));
            case "h":
                return Duration.ofHours(parseLong(ttlStr));
            case "m":
                return Duration.ofMinutes(parseLong(ttlStr));
            case "s":
                return Duration.ofSeconds(parseLong(ttlStr));
            default:
                return Duration.ofSeconds(Long.parseLong(ttlStr));
        }
    }

    private long parseLong(String ttlStr) {
        return Long.parseLong(ttlStr.substring(0, ttlStr.length() - 1));
    }

}

2、把TaRedisCacheManager交给spring管理

    /**
     * 自定义RedisCacheManager,用于在使用@Cacheable时设置ttl
     */
    @Bean({"redisCacheManager"})
    public RedisCacheManager redisCacheManager(RedisTemplate<?, ?> redisTemplate) {
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisTemplate.getConnectionFactory()));
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer()));
        return new TaRedisCacheManager(redisCacheWriter, redisCacheConfiguration);
    }

3、使用,为testCache设置过期时间为10小时

    @Cacheable(value = "testCache#10h", key = "#userId", condition = "#userId != null && #userName == null ")
    public String testCache(String userId, String userName) {
        System.out.println("=====================>");
        ThreadUtil.sleep(1000);
        return "success";
    }

注:该方案还是修改了原springCache的设计,而且不支持过期自动刷新,所以改造了一下,注解式[SpirngCache、Redis指定过期时间、到期自动刷新_csdn_Ty的博客-CSDN博客]

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值