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

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

org.springframework.bootspring-boot-starter-redis1.4.4.RELEASEorg.springframework.dataspring-data-redis1.8.1.RELEASEredis.clientsjedis2.9.0

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; } @Bean public 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); }// 初始化连接pooljedis.afterPropertiesSet(); // 获取连接templateStringRedisTemplate 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); }@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext; }@Overridepublic void afterPropertiesSet() {parseCacheExpire(applicationContext); }private void parseCacheExpire(ApplicationContext applicationContext) {final Map 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 cacheExpires) {ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() {@Overridepublic 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() {@Overridepublic 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小时
【SpringBoot配置Redis自定义过期时间操作】这样无疑的记录24小时的数量是不准确的
并且spring boot 中,默认使用了spring 来操作redis ,使存在每个redis中的值,都会加前面加入一些东西
1) "\xac\xed\x00\x05t\x00\x0bREDISUALIST"
SpringBoot配置Redis自定义过期时间操作
文章图片

我们在查找每个值的时候,并不知道在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 keys = redisTemplate.getConnectionFactory().getConnection().keys(key.getBytes()); byte[] bytes = keys.stream().findFirst().get(); Long ttl = redisTemplate.getConnectionFactory().getConnection().ttl(bytes); return ttl; }

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

    推荐阅读