SpringBoot Redis监听新增、修改、删除、过期事件(详细) 您所在的位置:网站首页 redis缓存过期时间原理 SpringBoot Redis监听新增、修改、删除、过期事件(详细)

SpringBoot Redis监听新增、修改、删除、过期事件(详细)

2023-07-28 18:33| 来源: 网络整理| 查看: 265

前言

项目中需要监听redis的一些事件比如键删除,修改,过期等。过期事件网上有很多例子可以参考,但修改或删除事件却很少。因为redis支持发布订阅所以其他的事件类型应该也是能实现的,通过过期事件监听结合上文键空间通知,我整理了相关代码,希望帮助需要的人快速解决问题。

代码搬运工搬自:

https://blog.csdn.net/qq_39648029/article/details/105072079

https://blog.csdn.net/huangbaoling66/article/details/102776551

 

一、能直接使用的过期事件监听

1、引入依赖

org.springframework.boot spring-boot-starter-data-redis

2、修改boot的redis配置

spring: #redis redis: database: 0 host: 127.0.0.1 password: redis_123456 port: 6379

3、在服务器中 修改redis.conf配置文件(原来notify-keyspace-events 属性是" " 空的,我们只需要填上“Ex”就行了),注意如果是阿里云挂载的redis,需要确定你领导让不让开放conf命令权限,因为源码里面有使用到conf get ..的命令方法。

notify-keyspace-events "Ex"

4、创建一个Redis监控类,用于监控过期的key,该类需继承KeyExpirationEventMessageListener

import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.listener.KeyExpirationEventMessageListener; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import java.nio.charset.StandardCharsets; /** * @program: SpringCloud * @description: redis Key过期监听 * @author: zhang yi * @create: 2020-03-24 14:14 */ public class KeyExpiredListener extends KeyExpirationEventMessageListener { public KeyExpiredListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } @Override public void onMessage(Message message, byte[] pattern) { System.out.println("过期key:" + message.toString()); } }

 5、创建Redis配置类

import com.zy.rabbitmq.base.Listener.KeyExpiredListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.listener.RedisMessageListenerContainer; /** * @program: SpringCloud * @description: redis配置类 * @author: zhang yi * @create: 2020-03-24 14:17 */ @Configuration public class RedisConfiguration { @Autowired private RedisConnectionFactory redisConnectionFactory; @Bean public RedisMessageListenerContainer redisMessageListenerContainer() { RedisMessageListenerContainer redisMessageListenerContainer = new RedisMessageListenerContainer(); redisMessageListenerContainer.setConnectionFactory(redisConnectionFactory); return redisMessageListenerContainer; } @Bean public KeyExpiredListener keyExpiredListener() { return new KeyExpiredListener(this.redisMessageListenerContainer()); } }

 

二、其他事件监听

由上一可以看继承的KeyExpirationEventMessageListener 类在spring中的源码

// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.data.redis.listener; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.core.RedisKeyExpiredEvent; import org.springframework.lang.Nullable; public class KeyExpirationEventMessageListener extends KeyspaceEventMessageListener implements ApplicationEventPublisherAware { private static final Topic KEYEVENT_EXPIRED_TOPIC = new PatternTopic("__keyevent@*__:expired"); @Nullable private ApplicationEventPublisher publisher; public KeyExpirationEventMessageListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } protected void doRegister(RedisMessageListenerContainer listenerContainer) { listenerContainer.addMessageListener(this, KEYEVENT_EXPIRED_TOPIC); } protected void doHandleMessage(Message message) { this.publishEvent(new RedisKeyExpiredEvent(message.getBody())); } protected void publishEvent(RedisKeyExpiredEvent event) { if (this.publisher != null) { this.publisher.publishEvent(event); } } public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } }

简单了解redis键空间通知是怎么回事: 参考文档http://redisdoc.com/topic/notification.html

键空间通知,所有通知以 keyspace@ 为前缀 键事件通知,所有通知以 keyevent@ 为前缀 所有命令都只在键真的被改动了之后,才会产生通知,比如删除foo会产生 键空间通知 “pmessage”,"__ key*__ : * “,”__ keyspace@0__:foo",“set” 和键事件通知 “pmessage”,"__ key*__ : *","__ keyevent@0__:set",“foo” ———————————————— 版权声明:本文为CSDN博主「huangbaoling66」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/huangbaoling66/article/details/102776551

如果要监听某个key的执行了什么操作,就订阅 keyspace@,监听某种操作动了哪些key,就订阅keyevent@。 这里我们需要监听哪些键被删除了,所以要监听删除动作"__ keyevent@0__:del"

对比上文spring写的listener有这么一句 private static final Topic KEYEVENT_EXPIRED_TOPIC = new PatternTopic("__keyevent@*__:expired"); 其他都是模式化的代码,只要修改对应的topic类型就能实现监听了。 删除:

import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.core.RedisKeyExpiredEvent; import org.springframework.data.redis.listener.KeyspaceEventMessageListener; import org.springframework.data.redis.listener.PatternTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.Topic; import org.springframework.lang.Nullable; public class KeyDeleteEventMessageListener extends KeyspaceEventMessageListener implements ApplicationEventPublisherAware { private static final Topic KEYEVENT_DELETE_TOPIC = new PatternTopic("__keyevent@*__:del"); @Nullable private ApplicationEventPublisher publisher; public KeyDeleteEventMessageListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } protected void doRegister(RedisMessageListenerContainer listenerContainer) { listenerContainer.addMessageListener(this, KEYEVENT_DELETE_TOPIC); } protected void doHandleMessage(Message message) { this.publishEvent(new RedisKeyExpiredEvent(message.getBody())); } protected void publishEvent(RedisKeyExpiredEvent event) { if (this.publisher != null) { this.publisher.publishEvent(event); } } public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } }

新增/修改:

package cn.fatri.jarvis.device.shadow.listener; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.core.RedisKeyExpiredEvent; import org.springframework.data.redis.listener.KeyspaceEventMessageListener; import org.springframework.data.redis.listener.PatternTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer; import org.springframework.data.redis.listener.Topic; import org.springframework.lang.Nullable; public class KeyUpdateEventMessageListener extends KeyspaceEventMessageListener implements ApplicationEventPublisherAware { private static final Topic KEYEVENT_DELETE_TOPIC = new PatternTopic("__keyevent@*__:set"); @Nullable private ApplicationEventPublisher publisher; public KeyUpdateEventMessageListener(RedisMessageListenerContainer listenerContainer) { super(listenerContainer); } protected void doRegister(RedisMessageListenerContainer listenerContainer) { listenerContainer.addMessageListener(this, KEYEVENT_DELETE_TOPIC); } protected void doHandleMessage(Message message) { this.publishEvent(new RedisKeyExpiredEvent(message.getBody())); } protected void publishEvent(RedisKeyExpiredEvent event) { if (this.publisher != null) { this.publisher.publishEvent(event); } } public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { this.publisher = applicationEventPublisher; } }

最后继承这些重写的监听类就就能对事件做业务操作了!

 

 



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有