app开发者平台在数字化时代的重要性与发展趋势解析
1248
2022-12-24
SpringBoot配置Redis自定义过期时间操作
SpringBoot配置Redis自定义过期时间
Redis配置依赖
SpringBoot-Reids配置文件
package com.regs.tms.common.redis;
@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;
}
}
自定义失效注解
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[] 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
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[] bytes = keys.stream().findFirst().get();
Long ttl = redisTemplate.getConnectionFactory().getConnection().ttl(bytes);
return ttl;
}
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~