Redis自2.8.0之后版本提供Keyspace Notifications功能,允许客户订阅Pub / Sub频道,以便以某种方式接收影响Redis数据集的事件。Redis监听器能监听到redis中过期的key是有个要求的,必须在redis配置文件redis.conf里面设置能够监听到key过期事件,步骤如下:

1.  在 Redis 的安装目录,找到redis.windows.conf,将notify-keyspace-events放开

这里写图片描述

参数说明如下:

这里写图片描述 2. 在 RedisConfig.java 中注入一个 redisMessageListenerContainer 的Bean 用于监听

@Configuration
public class RedisListenerConfig {

    @Bean
    public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory){
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        return container;
    }
}

3. 创建监听 key 过期类,来实现当事件触发时的具体操作

@Component
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {

    public Logger logger = LoggerFactory.getLogger(RedisKeyExpirationListener.class);

    public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 拿到key
        logger.info("监听Redis key过期,key:{},channel:{}", message.toString(), new String(pattern));
    }
}

4. 官方只提供了key过期时的回调事件,所以需要自定义创建监听 key 删除事件,查看redis官网

public class KeyDelEventMsgListener extends KeyspaceEventMessageListener implements ApplicationEventPublisherAware {

    public Logger logger = LoggerFactory.getLogger(KeyDelEventMsgListener.class);

    private static final Topic KEYEVENT_DELETE_TOPIC = new PatternTopic("__keyevent@*__:del");

    private ApplicationEventPublisher publisher;

    public KeyDelEventMsgListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    protected void doRegister(RedisMessageListenerContainer listenerContainer) {
        listenerContainer.addMessageListener(this, KEYEVENT_DELETE_TOPIC);
    }

    protected void publishEvent(RedisKeyExpiredEvent event) {
        if (this.publisher != null) {
            this.publisher.publishEvent(event);
        }
    }

    @Override
    protected void doHandleMessage(Message message) {
        this.publishEvent(new RedisKeyExpiredEvent(message.getBody()));
    }

    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.publisher = applicationEventPublisher;
    }
}

5. 创建监听 key 删除类

@Component
public class RedisKeyDeleteListener extends KeyDelEventMsgListener{

    public Logger logger = LoggerFactory.getLogger(RedisKeyDeleteListener.class);

    public RedisKeyDeleteListener(RedisMessageListenerContainer listenerContainer) {
        super(listenerContainer);
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        logger.info("监听Redis key删除,key:{},channel:{}", message.toString(), new String(pattern));    }
}

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐