1. redis配置

package cn.jianml.redis.config;import cn.jianml.redis.listener.RedisMessageListener;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration
public class LettuceRedisConfig {@Autowiredprivate RedisMessageListener redisMessageListener;@Bean@ConditionalOnClass(RedisOperations.class)public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper mapper = new ObjectMapper();mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);jackson2JsonRedisSerializer.setObjectMapper(mapper);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();// key采用 String的序列化方式template.setKeySerializer(stringRedisSerializer);// hash的 key也采用 String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用 jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的 value序列化方式采用 jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}@Beanpublic ChannelTopic expiredTopic() {return new ChannelTopic("__keyevent@0__:expired");}@BeanRedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {RedisMessageListenerContainer container = new RedisMessageListenerContainer();//注意添加自定义的监听器container.addMessageListener(redisMessageListener, expiredTopic());container.setConnectionFactory(connectionFactory);return container;}}

2 配置redis过期监听

package cn.jianml.redis.listener;import cn.jianml.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;@Slf4j
@Component
public class RedisMessageListener implements MessageListener {@Autowiredprivate RedisService redisService;@Overridepublic void onMessage(Message message, byte[] bytes) {log.info("监听过期key开始-->");String channel = new String(message.getChannel());byte[] body = message.getBody();System.out.println("过期的key为:" + new String(body));}
}

3 redis操作工具类

package cn.jianml.redis.service;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;/*** 定义常用的 Redis操作* @author wujian* @time 2020/1/7*/
@Service
public class RedisService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;/*** 指定缓存失效时间** @param key  键* @param time 时间(秒)* @return Boolean*/public Boolean expire(String key, Long time) {try {if (time > 0) {redisTemplate.expire(key, time, TimeUnit.SECONDS);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根据key获取过期时间** @param key 键 不能为 null* @return 时间(秒) 返回 0代表为永久有效*/public Long getExpire(String key) {return redisTemplate.getExpire(key, TimeUnit.SECONDS);}/*** 判断 key是否存在** @param key 键* @return true 存在 false不存在*/public Boolean hasKey(String key) {try {return redisTemplate.hasKey(key);} catch (Exception e) {e.printStackTrace();return false;}}/*** 删除缓存** @param key 可以传一个值 或多个*/public void del(String... key) {if (key != null && key.length > 0) {if (key.length == 1) {redisTemplate.delete(key[0]);} else {redisTemplate.delete(Arrays.asList(key));}}}/*** 普通缓存获取** @param key 键* @return 值*/public Object get(String key) {return key == null ? null : redisTemplate.opsForValue().get(key);}/*** 普通缓存放入** @param key   键* @param value 值* @return true成功 false失败*/public Boolean set(String key, Object value) {try {redisTemplate.opsForValue().set(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 普通缓存放入并设置时间** @param key   键* @param value 值* @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期* @return true成功 false 失败*/public Boolean set(String key, Object value, Long time) {try {if (time > 0) {redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);} else {set(key, value);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 递增** @param key   键* @param delta 要增加几(大于0)* @return Long*/public Long incr(String key, Long delta) {if (delta < 0) {throw new RuntimeException("递增因子必须大于0");}return redisTemplate.opsForValue().increment(key, delta);}/*** 递减** @param key   键* @param delta 要减少几(小于0)* @return Long*/public Long decr(String key, Long delta) {if (delta < 0) {throw new RuntimeException("递减因子必须大于0");}return redisTemplate.opsForValue().increment(key, -delta);}/*** HashGet** @param key  键 不能为 null* @param item 项 不能为 null* @return 值*/public Object hget(String key, String item) {return redisTemplate.opsForHash().get(key, item);}/*** 获取 hashKey对应的所有键值** @param key 键* @return 对应的多个键值*/public Map<Object, Object> hmget(String key) {return redisTemplate.opsForHash().entries(key);}/*** HashSet** @param key 键* @param map 对应多个键值* @return true 成功 false 失败*/public Boolean hmset(String key, Map<String, Object> map) {try {redisTemplate.opsForHash().putAll(key, map);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** HashSet 并设置时间** @param key  键* @param map  对应多个键值* @param time 时间(秒)* @return true成功 false失败*/public Boolean hmset(String key, Map<String, Object> map, Long time) {try {redisTemplate.opsForHash().putAll(key, map);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @return true 成功 false失败*/public Boolean hset(String key, String item, Object value) {try {redisTemplate.opsForHash().put(key, item, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 向一张hash表中放入数据,如果不存在将创建** @param key   键* @param item  项* @param value 值* @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间* @return true 成功 false失败*/public Boolean hset(String key, String item, Object value, Long time) {try {redisTemplate.opsForHash().put(key, item, value);if (time > 0) {expire(key, time);}return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 删除hash表中的值** @param key  键 不能为 null* @param item 项 可以使多个不能为 null*/public void hdel(String key, Object... item) {redisTemplate.opsForHash().delete(key, item);}/*** 判断hash表中是否有该项的值** @param key  键 不能为 null* @param item 项 不能为 null* @return true 存在 false不存在*/public Boolean hHasKey(String key, String item) {return redisTemplate.opsForHash().hasKey(key, item);}/*** hash递增 如果不存在,就会创建一个 并把新增后的值返回** @param key  键* @param item 项* @param by   要增加几(大于0)* @return Double*/public Double hincr(String key, String item, Double by) {return redisTemplate.opsForHash().increment(key, item, by);}/*** hash递减** @param key  键* @param item 项* @param by   要减少记(小于0)* @return Double*/public Double hdecr(String key, String item, Double by) {return redisTemplate.opsForHash().increment(key, item, -by);}/*** 根据 key获取 Set中的所有值** @param key 键* @return Set*/public Set<Object> sGet(String key) {try {return redisTemplate.opsForSet().members(key);} catch (Exception e) {e.printStackTrace();return null;}}/*** 根据value从一个set中查询,是否存在** @param key   键* @param value 值* @return true 存在 false不存在*/public Boolean sHasKey(String key, Object value) {try {return redisTemplate.opsForSet().isMember(key, value);} catch (Exception e) {e.printStackTrace();return false;}}/*** 将数据放入set缓存** @param key    键* @param values 值 可以是多个* @return 成功个数*/public Long sSet(String key, Object... values) {try {return redisTemplate.opsForSet().add(key, values);} catch (Exception e) {e.printStackTrace();return 0L;}}/*** 将set数据放入缓存** @param key    键* @param time   时间(秒)* @param values 值 可以是多个* @return 成功个数*/public Long sSetAndTime(String key, Long time, Object... values) {try {Long count = redisTemplate.opsForSet().add(key, values);if (time > 0)expire(key, time);return count;} catch (Exception e) {e.printStackTrace();return 0L;}}/*** 获取set缓存的长度** @param key 键* @return Long*/public Long sGetSetSize(String key) {try {return redisTemplate.opsForSet().size(key);} catch (Exception e) {e.printStackTrace();return 0L;}}/*** 移除值为value的** @param key    键* @param values 值 可以是多个* @return 移除的个数*/public Long setRemove(String key, Object... values) {try {return redisTemplate.opsForSet().remove(key, values);} catch (Exception e) {e.printStackTrace();return 0L;}}/*** 获取list缓存的内容** @param key   键* @param start 开始* @param end   结束 0 到 -1代表所有值* @return List*/public List<Object> lGet(String key, Long start, Long end) {try {return redisTemplate.opsForList().range(key, start, end);} catch (Exception e) {e.printStackTrace();return null;}}/*** 获取list缓存的长度** @param key 键* @return Long*/public Long lGetListSize(String key) {try {return redisTemplate.opsForList().size(key);} catch (Exception e) {e.printStackTrace();return 0L;}}/*** 通过索引 获取list中的值** @param key   键* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;*              index<0时,-1,表尾,-2倒数第二个元素,依次类推* @return Object*/public Object lGetIndex(String key, Long index) {try {return redisTemplate.opsForList().index(key, index);} catch (Exception e) {e.printStackTrace();return null;}}/*** 将list放入缓存** @param key   键* @param value 值* @return Boolean*/public Boolean lSet(String key, Object value) {try {redisTemplate.opsForList().rightPush(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return Boolean*/public Boolean lSet(String key, Object value, Long time) {try {redisTemplate.opsForList().rightPush(key, value);if (time > 0)expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @return Boolean*/public Boolean lSet(String key, List<Object> value) {try {redisTemplate.opsForList().rightPushAll(key, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 将list放入缓存** @param key   键* @param value 值* @param time  时间(秒)* @return Boolean*/public Boolean lSet(String key, List<Object> value, Long time) {try {redisTemplate.opsForList().rightPushAll(key, value);if (time > 0)expire(key, time);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 根据索引修改list中的某条数据** @param key   键* @param index 索引* @param value 值* @return Boolean*/public Boolean lUpdateIndex(String key, Long index, Object value) {try {redisTemplate.opsForList().set(key, index, value);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 移除N个值为value** @param key   键* @param count 移除多少个* @param value 值* @return 移除的个数*/public Long lRemove(String key, Long count, Object value) {try {return redisTemplate.opsForList().remove(key, count, value);} catch (Exception e) {e.printStackTrace();return 0L;}}
}

4application.yml配置

server:port: 8080spring:redis:database: 0 # Redis数据库索引(默认为0)host: 127.0.0.1 # Redis服务器地址port: 6379 # Redis服务器连接端口
#    password: 123456 # Redis服务器连接密码(默认为空)lettuce:pool:min-idle: 8 # 连接池中的最小空闲连接max-idle: 500 # 连接池中的最大空闲连接max-active: 2000 # 连接池最大连接数(使用负值表示没有限制)max-wait: 10000 # 连接池最大阻塞等待时间(使用负值表示没有限制)timeout: 5000 #连接超时时间level.cn.*:debug
logging:level:root: INFOcn.jianml.redis: DEBUG

5 logback 配置(文件名为 logback-spring.xml  此格式会被springboot默认加载  )

<?xml version="1.0" encoding="UTF-8"?>
<!--SpringBoot 官方推荐优先使用带有 -spring 的文件名作为你的日志配置(如使用 logback-spring.xml,而不是logback.xml),SpringBoot 会对以 -spring 结尾的日志配置添加一些 SpringBoot 所特有的配置项。-->
<configuration><!--定义日志文件的存储地址,使用绝对路径--><property name="LOG_HOME" value="d:/logs"/><!-- Console 输出设置 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符--><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern><charset>utf8</charset></encoder></appender><!-- 按照每天生成日志文件 --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!--日志文件输出的文件名--><fileNamePattern>${LOG_HOME}/xc.%d{yyyy-MM-dd}.log</fileNamePattern><maxHistory>30</maxHistory><totalSizeCap>1GB</totalSizeCap><!-- fileNamePattern 定义了日志的切分方式,上例为按日切分。maxHistory 表示日志的保留时长,上例为保留 30 天的日志。totalSizeCap 表示日志文件的上限大小。例如设置为 1GB 的话,那么当达到该值时,会删除旧的日志。--></rollingPolicy><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><!-- 异步输出 --><appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"><!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --><discardingThreshold>0</discardingThreshold><!-- 更改默认的队列的深度,该值会影响性能.默认值为256 --><queueSize>512</queueSize><!-- 添加附加的appender,最多只能添加一个 --><appender-ref ref="FILE"/></appender><logger name="org.apache.ibatis.cache.decorators.LoggingCache" level="INFO" additivity="false"><appender-ref ref="CONSOLE"/></logger><logger name="org.springframework.boot" level="DEBUG"/><root level="info"><!--<appender-ref ref="ASYNC"/>--><appender-ref ref="FILE"/><appender-ref ref="CONSOLE"/></root>
</configuration>

springboot集成redis,及过期监听相关推荐

  1. redis开启过期监听

    java项目中,场景:订单没有付款到期取消订单,使用的是redis过期监听来做的,做个笔记!首先使用该功能需要下载2.8.0及以上的版本,这一部分详细内容可以访问redis官网:http://redi ...

  2. redis依赖_请勿过度依赖 Redis 的过期监听

    阅读本文大概需要 5 分钟. 来自:http://juejin.im/post/6844904158227595271 Redis 过期监听场景 业务中有类似等待一定时间之后执行某种行为的需求 , 比 ...

  3. Redis key过期监听

    RedisKey超时监听 Key过期会不会立即删除? 不会立即删除:由于Redis属于单线程,主服务不会第一时间删除Key.所有Key不会在第一时间被删除. 删除机制: (1)定期删除:Redis每一 ...

  4. Springboot redis多数据源过期监听案例

    在上一篇Springboot redis多数据源案例中,我们实现了springboot下多数据源的案例. 本篇博客在此基础上,实现多数据源过期监听事件: 监听器配置类: package com.xin ...

  5. Redis自动过期机制之key的过期监听(7)

    Redis中的自动过期机制 前言 1.使用Redis Key自动过期机制 2.Springboot整合key过期监听 2.1. 创建表 order_number 2.2核心代码 2.2.1 核心代码 ...

  6. redis过期监听性能_基于Redis的延迟处理

    延迟处理是一个非常常用的一个功能; 例如, 下单成功后,在30分钟内没有支付,自动取消订单; 延迟队列便是延迟处理中最常见的实现方式; 先一起看下JDK中延迟队列是如何实现的. JUC的DelayQu ...

  7. Java集成Redis key过期通知

    为什么要使用过期通知呢? 捕获Redis中过期的Key,解锁新姿势.比如有个用户会员的模块,那么可以在redis添加一个用户会员的有效时Key,然后在Java项目中捕获,处理相关的逻辑. 一.开启Re ...

  8. SpringBoot集成Redis用法笔记

    今天给大家整理一下SpringBoot集成Redis用法笔记,希望对大家能有所帮助! 一.Redis优点介绍 1.速度快 不需要等待磁盘的IO,在内存之间进行的数据存储和查询,速度非常快.当然,缓存的 ...

  9. redistemplate hash 过期时间_Redis过期监听——订单超时-取消

    最近在做电商项目,涉及支付超时处理的几种方式.[记录哈使用redis监听处理] 提交订单的时候,支付-超过了有效时间则支付状态自动更新为已取消. 欢迎交流 redis过期监听的实现: 1.修改redi ...

最新文章

  1. 一个母婴电子商务网站贝贝网的大数据平台及机器学习实践【转】
  2. android toolbar 开发总结
  3. 在AFN中使用NSXMLParser解析服务器返回的XML数据
  4. java定义静态set集合_java集合之set
  5. Android:源码环境编译自定义的APP到ROM(System Image)中
  6. 银行营业网点管理系统——entity类(Branches)
  7. java httpclient 异步请求_Java利用httpasyncclient进行异步HTTP请求
  8. 通过ActionTrail监控AccessKey的使用
  9. java能做三国杀的特效吗_能不能在游戏中关闭将灵攻击特效,太恶心了
  10. (65)Verilog HDL多模块重复例化:generate for
  11. linux mint 引导类型,LinuxMint18配置Grub2默认启动操作系统
  12. android屏幕截图代码,android中实现整个屏幕截图的代码
  13. 苏州大学计算机复试python_苏州大学计算机考研复试经验总结
  14. Adobe Photoshop CC 2014图文永久安装教程
  15. Linux编译DuiLib库报error: no matches converting function ‘ItemComareFunc’ to type ‘__compar_d_fn_t错误解决
  16. 数据清洗之微博内容清洗
  17. 内网IP可以申请SSL证书吗
  18. microsoft excel使用技巧和问题解决
  19. SQL Server Reporting Services
  20. SpringBoot+LayUI+MybatisPlus+Echarts图表 前后端分离 实现数据统计功能

热门文章

  1. 面试面经|Java面试Redis面试题
  2. 网络安全实验室 注入关通关writeup
  3. 在上传文件时限制上传文件的大小,并捕捉超过文件大小限制的异常
  4. 2022年安全员-A证考试题库及在线模拟考试
  5. 解决 PopupWindow 使其点击外部不消失
  6. OPPOReno系列怎么选?2199起售,Reno7系列三款手机的差别要知道
  7. 华为鸿蒙开启王者荣耀,王者荣耀猪队友,游戏更新曝光华为新平板,直接搭载鸿蒙2.0?...
  8. 通过浏览器链接打开本地应用(APP)
  9. 数据库的增删改查语法和多表联查方式
  10. 安卓手机来电防火墙_安卓手机:网络摄像头发现、虚拟来电短信、加速器