SpringBoot配置Redis自定义过期时间
Redis配置依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
< 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配置文件
1
|
package com.regs.tms.common.redis; |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
@Configuration @EnableCaching // 启用缓存,这个注解很重要 @ConfigurationProperties (prefix = "spring.redis" ) @Data public 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 ); } // 初始化连接pool jedis.afterPropertiesSet(); // 获取连接template StringRedisTemplate temple = new StringRedisTemplate(); temple.setConnectionFactory(jedis); return temple; } } |
自定义失效注解
1
|
package com.regs.tms.common.redis.annotation; |
1
2
3
4
5
6
|
@Retention (RetentionPolicy.RUNTIME) @Target ({ElementType.METHOD, ElementType.TYPE}) public @interface CacheDuration { //Sets the expire time (in seconds). public long duration() default 60 ; } |
自定义失效配置
1
|
package com.regs.tms.common.redis.annotation; |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
/** * 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 中,增加一个方法
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/** * 获取指定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; } |
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/qq_31973845/article/details/85067252