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