RedisKey的失效监听器KeyExpirationEventMessageListener问题

 更新时间:2024年05月27日 10:24:13   作者:是小故事呀  
这篇文章主要介绍了RedisKey的失效监听器KeyExpirationEventMessageListener问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

RedisKey的失效监听器KeyExpirationEventMessageListener

利用KeyExpirationEventMessageListener实现redis的key失效监听。

在使用redis时,所有的key都要设置过期时间,过期之后,redis就会把对应的key清除掉。

此方法可以监听redis的key失效,在失效时做一些逻辑处理。话不多说,上代码。

依赖

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

实现

import com.upbim.twin.park.common.constans.Constants;
import com.upbim.twin.park.server.strategy.PushMessageStrategyContext;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.Topic;
import org.springframework.stereotype.Service;

import java.util.UUID;

import static com.upbim.twin.park.common.constans.Constants.TRACE_ID;
@Slf4j
@Service
public class AgentOrderRedisKeyExpiredListener extends KeyExpirationEventMessageListener {

    @Autowired
    private PushMessageStrategyContext pushMessageStrategyContext;
    @Autowired
    private RedisProperties redisProperties;

    /**
     * Creates new  MessageListener for {@code __keyevent@*__:expired} messages.
     *
     * @param listenerContainer must not be {@literal null}.
     */
    public AgentOrderRedisKeyExpiredListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    protected void doRegister(RedisMessageListenerContainer listenerContainer) {

        // 只监听指定redis数据库的key过期事件
        Topic topic = new PatternTopic(String.format("__keyevent@%s__:expired", redisProperties.getDatabase()));
        listenerContainer.addMessageListener(this, topic);
    }

    @Override
    protected void doHandleMessage(Message message) {

        // 订阅的topic: new String(message.getChannel(), UTF_8) --->  "__keyevent@0__:expired"
        // 触发key失效发布的key:new String(message.getBody(), UTF_8) --->  "demoKey"
        MDC.put(TRACE_ID, UUID.randomUUID().toString());
        try {
            log.info(String.format("Redis key expired event:%s", message.toString()));

            String beanName = message.toString().split(Constants.COLON)[Constants.ONE];
            pushMessageStrategyContext.handleRedisExpireKey(beanName, message.toString());
            super.doHandleMessage(message);
        } finally {

            MDC.clear();
        }
    }

}

监听处理类

package com.upbim.twin.park.server.strategy;

import com.google.common.collect.Maps;
import com.upbim.twin.park.server.strategy.nozzle.PushMessageStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;

@Slf4j
@Component
public class PushMessageStrategyContext {

    /**
     * 使用线程安全的ConcurrentHashMap存储所有实现Strategy接口的Bean
     * key:beanName
     * value:实现Strategy接口Bean
     */
    private final Map<String, PushMessageStrategy> strategyMap = Maps.newConcurrentMap();

    /**
     * 注入所有实现了Strategy接口的Bean
     *
     * @param strategyMap the strategy map
     */
    @Autowired
    public PushMessageStrategyContext(Map<String, PushMessageStrategy> strategyMap) {
        strategyMap.forEach(this.strategyMap::put);
    }

    /**
     * 策略监听redis所有过期key
     *
     * @param beanName        the bean name
     * @param redisInvalidKey the redis invalid key
     * @return
     */
    public void handleRedisExpireKey(String beanName, String redisInvalidKey) {

        if (Objects.nonNull(strategyMap.get(beanName))) {
            strategyMap.get(beanName).handleRedisExpireKey(redisInvalidKey);
        } else {
            log.warn("找不到对应的策略:{}", strategyMap.get(beanName));
        }
    }

}
public interface PushMessageStrategy {
  void handleRedisExpireKey(String redisInvalidKey);
}

大家在使用的时候,可以针对自己不同的场景,实现PushMessageStrategy 接口,重写handleRedisExpireKey方法。

在方法中处理不同的逻辑。

首先,在redis’中有key失效过期时,AgentOrderRedisKeyExpiredListener 监听到redis实现,会执行doHandleMessage方法,方法中会调用PushMessageStrategyContext 的获取不同策略的Bean,进行业务操作。

至此,监听redis中key失效完成。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot RestTemplate 简单包装解析

    SpringBoot RestTemplate 简单包装解析

    这篇文章主要介绍了SpringBoot RestTemplate 简单包装解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • 关于Spring Boot项目的 log4j2 核弹漏洞问题(一行代码配置搞定)

    关于Spring Boot项目的 log4j2 核弹漏洞问题(一行代码配置搞定)

    相信昨天,很多小伙伴都因为Log4j2的史诗级漏洞忙翻了吧,不过我看到群里发出来的各种修复方法,还真是不好看...所以这里也提一下Spring Boot用户怎么修复最简单吧,对Spring Boot log4j2 核弹漏洞问题感兴趣的朋友参考下吧
    2021-12-12
  • idea配置gradle全过程

    idea配置gradle全过程

    安装Gradle首先需要解压安装包到指定目录,随后配置环境变量GRDLE_HOME和GRADLE_USER_HOME,这里的GRADLE_USER_HOME是指文件下载的路径,安装后,通过命令行输入gradle -v来测试是否安装成功,对于Idea的配置,需要通过File->Setting->Gradle进行
    2024-10-10
  • SpringBoot + Maven 多环境打包实现方法

    SpringBoot + Maven 多环境打包实现方法

    本文介绍如何在SpringBoot项目中实现不同环境的配置切换及Maven多环境打包的方法,包括配置文件的选择与加载机制,以及如何通过POM文件进行多环境打包,感兴趣的朋友跟随小编一起看看吧
    2025-12-12
  • 用Rational Rose逆向工程(java)生成类图(教程和错误解决)

    用Rational Rose逆向工程(java)生成类图(教程和错误解决)

    Rational Rose有个很方便的功能,将项目中的JAVA代码自动转换成UML类图
    2013-02-02
  • 一些java二进制的相关基础知识

    一些java二进制的相关基础知识

    这篇文章主要介绍了一些java二进制的相关基础知识,在Java语言中byte代表最小计量单位,byte由8位2进制数组成。,需要的朋友可以参考下
    2019-06-06
  • IDEA中设置背景颜色的步骤

    IDEA中设置背景颜色的步骤

    在IntelliJ IDEA中,用户可以通过访问【Settings】或【Preferences】菜单,进入【Editor】>【ColorScheme】选项来选择和调整编辑区域的颜色方案,此外,通过【Appearance & Behavior】>【Appearance】选项
    2024-09-09
  • 一文详解SpringBoot如何优雅地实现异步调用

    一文详解SpringBoot如何优雅地实现异步调用

    SpringBoot想必大家都用过,但是大家平时使用发布的接口大都是同步的,那么你知道如何优雅的实现异步呢?这篇文章就来和大家详细聊聊
    2023-03-03
  • Java 基于AQS实现自定义同步器的示例

    Java 基于AQS实现自定义同步器的示例

    这篇文章主要介绍了Java 基于AQS实现自定义同步器的示例,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-03-03
  • 用java的spring实现一个简单的IOC容器示例代码

    用java的spring实现一个简单的IOC容器示例代码

    本篇文章主要介绍了用java实现一个简单的IOC容器示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03

最新评论