SpringBoot配置Redis自定义过期时间操作

SpringBoot配置Redis自定义过期时间Redis配置依赖

<dependency>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-redis</artifactId>        <version>1.4.4.RELEASE</version>      </dependency>      <dependency>        <groupId>org.springframework.data</groupId>        <artifactId>spring-data-redis</artifactId>        <version>1.8.1.RELEASE</version>      </dependency>      <dependency>        <groupId>redis.clients</groupId>        <artifactId>jedis</artifactId>        <version>2.9.0</version></dependency>

SpringBoot-Reids配置文件

package com.regs.tms.common.redis;
@Configuration@EnableCaching// 启用缓存,这个注解很重要@ConfigurationProperties(prefix = "spring.redis")@Datapublic class RedisCacheConfig extends CachingConfigurerSupport {private String host;private Integer port;private Integer database;private String password;@Bean("redisTemplate")public RedisTemplate redisTemplate(RedisConnectionFactory factory) {    StringRedisTemplate template = new StringRedisTemplate();    template.setConnectionFactory(factory);    //使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值    Jackson2JsonRedisSerializer serializer = new Jackson2JsonRedisSerializer(Object.class);    ObjectMapper mapper = new ObjectMapper();    mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);    mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);    serializer.setObjectMapper(mapper);    template.setValueSerializer(serializer);    template.setHashValueSerializer(serializer);    // 设置键(key)的序列化采用StringRedisSerializer。    template.setKeySerializer(new StringRedisSerializer());    template.setHashKeySerializer(new StringRedisSerializer());    //打开事务支持    template.setEnableTransactionSupport(true);    template.afterPropertiesSet();    return template;}@Beanpublic PlatformTransactionManager transactionManager(DataSource dataSource) throws SQLException {    //配置事务管理器    return new DataSourceTransactionManager(dataSource);}@Bean("stringRedisTemplate")public StringRedisTemplate stringRedisTemplate() {    Integer port = this.port == null ? 6379 : this.port;    JedisConnectionFactory jedis = new JedisConnectionFactory();    jedis.setHostName(host);    jedis.setPort(port);    if (StringUtils.isNotEmpty(password)) {        jedis.setPassword(password);    }    if (database != null) {        jedis.setDatabase(database);    } else {        jedis.setDatabase(0);    }    // 初始化连接pool    jedis.afterPropertiesSet();    // 获取连接template    StringRedisTemplate temple = new StringRedisTemplate();    temple.setConnectionFactory(jedis);    return temple;}}

自定义失效注解

package com.regs.tms.common.redis.annotation;
@Retention(RetentionPolicy.RUNTIME)@Target({ElementType.METHOD, ElementType.TYPE})public @interface CacheDuration {    //Sets the expire time (in seconds).    public long duration() default 60;}

自定义失效配置

package com.regs.tms.common.redis.annotation;
 /** * ExpireCacheManager,继承自RedisCacheManager, * 用于对@CacheExpire解析及有效期的设置 */public class RedisExpireCacheManager extends RedisCacheManager implements ApplicationContextAware, InitializingBean {    private ApplicationContext applicationContext;    public RedisExpireCacheManager(RedisTemplate redisTemplate) {        super(redisTemplate);    }    @Override    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {        this.applicationContext = applicationContext;    }    @Override    public void afterPropertiesSet() {        parseCacheExpire(applicationContext);    }    private void parseCacheExpire(ApplicationContext applicationContext) {        final Map<String, Long> cacheExpires = new HashMap<>(16);        //扫描有注解        String[] beanNames = applicationContext.getBeanNamesForAnnotation(Cacheable.class);        for (String beanName : beanNames) {            final Class clazz = applicationContext.getType(beanName);            addCacheExpires(clazz, cacheExpires);        }        //设置有效期        super.setExpires(cacheExpires);    }    private void addCacheExpires(final Class clazz, final Map<String, Long> cacheExpires) {        ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {            @Override            public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {                ReflectionUtils.makeAccessible(method);                //根据CacheExpire注解获取时间                CacheExpire cacheExpire = findCacheExpire(clazz, method);                if (cacheExpire != null) {                    Cacheable cacheable = findAnnotation(method, Cacheable.class);                    String[] cacheNames = isEmpty(cacheable.value()) ? new String[]{} : cacheable.value();                    for (String cacheName : cacheNames) {                        cacheExpires.put(cacheName, cacheExpire.expire());                    }                }            }        }, new ReflectionUtils.MethodFilter() {            @Override            public boolean matches(Method method) {                return null != findAnnotation(method, Cacheable.class);            }        });    }    /**     * CacheExpire标注的有效期,优先使用方法上标注的有效期     *     * @param clazz     * @param method     * @return     */    private CacheExpire findCacheExpire(Class clazz, Method method) {        CacheExpire methodCache = findAnnotation(method, CacheExpire.class);        if (null != methodCache) {            return methodCache;        }        CacheExpire classCache = findAnnotation(clazz, CacheExpire.class);        if (null != classCache) {            return classCache;        }        return null;    }}

spring boot 使用redis 超时时间重新设置

如果要计算每24小时的下单量,

通常的做法是,取出旧值,进行加一在设置回去,

但是这样就出现了一个问题

第二次设置值的时候,把超时时间重新设置成个24小时

这样无疑的记录24小时的数量是不准确的

并且spring boot 中,默认使用了spring 来操作redis ,使存在每个redis中的值,都会加前面加入一些东西

1) “\xac\xed\x00\x05t\x00\x0bREDISUALIST”

我们在查找每个值的时候,并不知道在key前面需要加点什么.

所以我们必须要用keys 这个命令 ,来匹配 我们需要查找的key,来取第一个

然后我们用 ttl 命令 返回指定key的剩余时间 ,重新设置回去,而不是设置24小时,这样就实现了24小时累加一次

在redisService 中,增加一个方法

/**     * 获取指定key的剩余超时时间,key最好是唯一的,有特点的,最好不要匹配出多个 例子 *111 取出 "\xac\xed\x00\x05t\x00\x0b111"     * 返回剩余秒数     * @param key     * @return     * create by jcd     */    public Long ttlByKey(@NotNull String key){        Set<byte[]> keys = redisTemplate.getConnectionFactory().getConnection().keys(key.getBytes());        byte[] bytes = keys.stream().findFirst().get();        Long ttl = redisTemplate.getConnectionFactory().getConnection().ttl(bytes);        return ttl;    }

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

你不勇敢,没人替你坚强!

SpringBoot配置Redis自定义过期时间操作

相关文章:

你感兴趣的文章:

标签云: