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)); }
}