zoukankan      html  css  js  c++  java
  • spring cache设置指定Key过期时间

    spring cache 集成redis是基于spring-data-redis组件开发的一直通过注解就能轻松实现redis缓存操作的框架。
    但原生的spring cache不支持缓存过期,默认都是没有过期时间的,以下实现自定义缓存过期时间。

    spring-data-redis版本是1.8.11,所以需要使用此版本或者兼容此版本的其他版本。

    先看spring的RedisCacheManager类代码:

    	protected RedisCache createCache(String cacheName) {
    		long expiration = computeExpiration(cacheName);
    		return new RedisCache(cacheName, (usePrefix ? cachePrefix.prefix(cacheName) : null), redisOperations, expiration,
    				cacheNullValues);
    	}
    
    	protected long computeExpiration(String name) {
    		Long expiration = null;
    		if (expires != null) {
    			expiration = expires.get(name);
    		}
    		return (expiration != null ? expiration.longValue() : defaultExpiration);
    	} 

    其中expiration变量其实就是过期时间(单位是秒),如果我们不做任何事情,那么expiration 就是defaultExpiration,这个值是0,也就是永不过期。所以我们可以从这个入手,自定义一个RedisCacheManager,覆盖createCache方法。

    自定义类:CustomizerRedisCacheManager

    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.math.NumberUtils;
    import org.springframework.cache.Cache;
    import org.springframework.data.redis.cache.RedisCache;
    import org.springframework.data.redis.cache.RedisCacheManager;
    import org.springframework.data.redis.core.RedisOperations;
    import org.springframework.util.CollectionUtils;
    
    import java.util.*;
    
    /**
     * @Description RedisCacheManager 
     * @Author huangd
     * @Date 2019-12-31 16:09
     **/
    @Slf4j
    public class CustomizerRedisCacheManager extends RedisCacheManager {
    
        private static final char SEPARATOR = '#';  // 过期时间分隔符,可以用其他符号
    
        public CustomizerRedisCacheManager(RedisOperations redisOperations) {
            super(redisOperations);
        }
    
        @Override
        protected RedisCache createCache(String cacheName) {
            long defaultExpiration = computeExpiration(cacheName);
            int expireIndex = cacheName.indexOf(SEPARATOR);
            if (expireIndex > 0) {
                defaultExpiration = getExpirationTime(cacheName, expireIndex, defaultExpiration);
                cacheName = cacheName.substring(0, expireIndex);
            }
    
            return new RedisCache(cacheName, (isUsePrefix() ? getCachePrefix().prefix(cacheName) : null),
                    getRedisOperations(), defaultExpiration);
        }
    
        /**
         * 缓存时间
         * @param name cacheName cache#3600
         * @param expireIndex
         * @param defaultExpiration 默认过期时间
         * @return
         */
        protected long getExpirationTime(String name, int expireIndex, long defaultExpiration) {
            String expirationAsString = name.substring(expireIndex + 1);
            try {
                Long expiration = NumberUtils.toLong(expirationAsString, defaultExpiration);
                return expiration.longValue();
            } catch (Exception e) {
                log.error("获取指定cacheName:{},缓存失效时间异常:{}", name, e.getMessage());
            }
    
            return defaultExpiration;
        }
    
    }
     

    设置redis的key序列化

    @Configuration
    public class CustomCachingConfigurerSupport extends CachingConfigurerSupport {
    
        @Bean
        public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
            RedisTemplate<Object, Object> template = new RedisTemplate<>();
            template.setConnectionFactory(redisConnectionFactory);
            template.setKeySerializer(new StringRedisSerializer());
            template.setHashKeySerializer(new StringRedisSerializer());
            template.afterPropertiesSet();
            return template;
        }
    
        @Bean
        public CustomizerRedisCacheManager redisCacheManager(RedisTemplate redisTemplate) {
            CustomizerRedisCacheManager redisCacheManager = new CustomizerRedisCacheManager(redisTemplate);
            redisCacheManager.setUsePrefix(true); // 写入redis中保留cacheName前缀
            return redisCacheManager;
    
        }
    } 

    使用@Cacheable验证缓存失效时间:

    @Cacheable(value = "ota.vehicle.series#20", key = "#k + '_' + 123")
        public String testExpire(String k) {
            return "test expire";
        } 

    缓存20秒后过期,效果如下:
    在这里插入图片描述
    20秒后过期,key被删除
    在这里插入图片描述

    这里需要注意一点:因为cacheName带上了#20,这样写到redis中也会带上这个前缀,所以需要去掉这个前缀,上面CustomizerRedisCacheManager 类中cacheName = cacheName.substring(0, expireIndex);
    就是将此部分截断再写入。

     转自:https://blog.csdn.net/huangdi1309/article/details/103784115?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control
     
  • 相关阅读:
    默认约束(十六)
    唯一约束(十五)
    主键约束(十四)
    自动编号(十三)
    空值(NULL)和非空(NOT NULL)(十二)
    Codeforces Round #249 (Div. 2) A B
    MySQL 採用Xtrabackup对数据库进行全库备份
    强算KMeans聚类算法演示器
    提高短信营销效果的四大技巧分析
    14年7月总结
  • 原文地址:https://www.cnblogs.com/javalinux/p/14356102.html
Copyright © 2011-2022 走看看