Redis 过期事件监听器完整实现
要使用 Redis 过期事件监听器来更新数据库状态,我们需要确保 Redis 的事件通知已启用,并实现监听器来捕获过期的键,并根据需要更新数据库。
步骤 1:启用 Redis 过期事件通知
需要在 Redis 配置文件中启用键事件通知。可以在 Redis 配置文件 redis.conf
中添加以下配置:
notify-keyspace-events Ex
如果使用 Docker 运行 Redis,可以在启动时传入参数:
docker run -d redis redis-server --notify-keyspace-events Ex
步骤 2:Redis 过期事件监听器代码
下面是完整的 Redis 监听器实现,用于捕获过期的键并更新用户状态:
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.stereotype.Component;
@Component
public class RedisExpiredListener implements MessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
String expiredKey = message.toString();
// 判断是否为用户信息缓存的键
if (expiredKey.startsWith("userInfo:")) {
try {
Long userId = Long.valueOf(expiredKey.split(":")[1]);
updateUserStatus(userId);
} catch (NumberFormatException e) {
System.err.println("解析用户 ID 失败:" + expiredKey);
}
}
}
/**
* 更新数据库中的用户状态
*
* @param userId 用户 ID
*/
private void updateUserStatus(Long userId) {
System.out.println("用户 " + userId + " 的 token 已过期,更新状态...");
// TODO: 在这里编写更新数据库的逻辑
// 示例:userService.updateUserStatusToExpired(userId);
}
}
步骤 3:在 Spring Boot 中启用监听
需要将 Redis 监听器注册到 Redis 连接工厂中。
在你的 Redis 配置类中进行如下配置:
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.ChannelTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
@Configuration
public class RedisConfig {
@Bean
public RedisMessageListenerContainer redisContainer(RedisConnectionFactory connectionFactory,
RedisExpiredListener expiredListener) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
// 监听所有键空间事件(包括过期事件)
container.addMessageListener(expiredListener, new ChannelTopic("__keyevent@0__:expired"));
return container;
}
}
步骤 4:示例数据库更新逻辑
在监听器中,你可以调用用户服务(userService
)来更新数据库中的用户状态:
@Autowired
private UserService userService;
private void updateUserStatus(Long userId) {
System.out.println("用户 " + userId + " 的 token 已过期,更新状态...");
userService.updateUserStatusToExpired(userId);
}
在 UserService
中实现状态更新:
@Service
public class UserService {
public void updateUserStatusToExpired(Long userId) {
// 更新数据库中的用户状态为已过期
System.out.println("正在将用户 " + userId + " 的状态更新为已过期...");
// 执行数据库更新操作(如使用 MyBatis 或 JPA)
}
}
总结
- 启用 Redis 的键事件通知:确保 Redis 配置中启用了
notify-keyspace-events Ex
选项。 - 实现 Redis 监听器:捕获过期事件并更新用户状态。
- 注册监听器到 Spring 容器:通过
RedisMessageListenerContainer
监听键的过期事件。 - 更新数据库状态:在监听器中调用服务层逻辑,完成数据库更新。
这样,当 Redis 中的用户缓存键过期时,监听器会自动触发,并更新数据库中的用户状态。