一、前提准备
监听redis的key过期,必须配置redis(笔者redis:6.2.5)
# 开启过期监听(空串关闭)
# notify-keyspace-events ""
notify-keyspace-events Ex
二、项目代码
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
application.yml
spring:
redis:
host: 192.168.1.17
password: HSJissmart.1215
port: 6379
ssl: false
#连接超时时间 这里用的是Duration时间类型,这里配置是是48小时,如果你不想你的连接超时,把这个配置给注掉
#connect-timeout: PT48H
#读取数据超时时间,这里5秒查不到数据就超时
timeout: PT5S
database: 8
RedisConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;
@Component
public class RedisConfig {
/**
* @Description:配置Redis消息监听容器
* @author HeShengjin 2356899074@qq.com
* @date 2023/1/13 10:34
*/
@Bean
public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
return container;
}
}
RedisKeyExpirationListener.java
import lombok.extern.slf4j.Slf4j;
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.stereotype.Component;
import java.nio.charset.StandardCharsets;
/**
* @Description:编写一个类交由spring管理并继承KeyExpirationEventMessageListener,一个项目中可有多个监听器实例
* @author HeShengjin 2356899074@qq.com
* @date 2023/1/13 10:35
*/
@Component
@Slf4j
public class RedisKeyExpirationListener extends KeyExpirationEventMessageListener {
public RedisKeyExpirationListener(RedisMessageListenerContainer listenerContainer) {
super(listenerContainer);
}
/**
* @Description:监听db:8
* @author HeShengjin 2356899074@qq.com
* @date 2023/1/13 10:39
*/
@Override
protected void doRegister(RedisMessageListenerContainer listenerContainer) {
//database: 8
listenerContainer.addMessageListener(this, new PatternTopic("__keyevent@8__:expired"));
}
/**
* 过期消息
*
* @param message key
* @param pattern 消息事件
* @return void
* @author lei
* @date 2022-09-27 10:17:54
*/
@Override
public void onMessage(Message message, byte[] pattern) {
String expiredKey = message.toString();
if (expiredKey.contains("TIME_OUT_KEY")) { // 判断是否是想要监听的过期key
log.info("redis TIME_OUT_KEY过期:{}", expiredKey);
//pattern:__keyevent@*__:expired
log.info("redis pattern:{}", new String(pattern, StandardCharsets.UTF_8));
// TODO 业务逻辑
}
}
}
SpringBootMainApplication.java
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.concurrent.TimeUnit;
@SpringBootApplication
public class SpringBootMainApplication implements CommandLineRunner {
@Autowired
private StringRedisTemplate stringRedisTemplate;
public static void main(String[] args) {
SpringApplication.run(SpringBootMainApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
try {
stringRedisTemplate.opsForValue().set("TIME_OUT_KEY_123456789","123456789",5, TimeUnit.MINUTES);
stringRedisTemplate.opsForValue().set("TIME_OUT_KEY_666666666","666666666",15, TimeUnit.MINUTES);
stringRedisTemplate.opsForValue().set("TIME_OUT_KEY_888888888","888888888",30, TimeUnit.MINUTES);
} catch (Exception e) {
e.printStackTrace();
}
}
}