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配置⽂件
dis;
@Configuration
@EnableCaching// 启⽤缓存,这个注解很重要
@ConfigurationProperties(prefix = "dis")
@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);
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;
}
}
⾃定义失效注解
dis.annotation;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface CacheDuration {
//Sets the expire time (in seconds).
public long duration() default 60;
}
⾃定义失效配置
dis.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 = BeanNamesForAnnotation(Cacheable.class);
for (String beanName : beanNames) {
final Class clazz = Type(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, pire());
}
}
}
}, 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;
springframework事务
}
return null;
}
}
spring boot 使⽤redis 超时时间重新设置
如果要计算每24⼩时的下单量,
通常的做法是,取出旧值,进⾏加⼀在设置回去,
但是这样就出现了⼀个问题
第⼆次设置值的时候,把超时时间重新设置成个24⼩时
这样⽆疑的记录24⼩时的数量是不准确的
并且spring boot 中,默认使⽤了spring 来操作redis ,使存在每个redis中的值,都会加前⾯加⼊⼀些东西
1) " ac ed 00 05t 00 0bREDISUALIST"
我们在查每个值的时候,并不知道在key前⾯需要加点什么.
所以我们必须要⽤keys 这个命令,来匹配我们需要查的key,来取第⼀个
然后我们⽤ ttl 命令返回指定key的剩余时间,重新设置回去,⽽不是设置24⼩时,这样就实现了24⼩时累加⼀次在redisService 中,增加⼀个⽅法
/**
* 获取指定key的剩余超时时间,key最好是唯⼀的,有特点的,最好不要匹配出多个例⼦ *111 取出 " ac ed 00 05t 00 0b111"
* 返回剩余秒数
* @param key
* @return
* create by jcd
*/
public Long ttlByKey(@NotNull String key){
Set<byte[]> keys = ConnectionFactory().getConnection().Bytes());
byte[] bytes = keys.stream().findFirst().get();
Long ttl = ConnectionFactory().getConnection().ttl(bytes);
return ttl;
}
以上为个⼈经验,希望能给⼤家⼀个参考,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。