当前位置: 首页
数据库
Spring Boot中使用Redis发布订阅功能并配置消息监听器容器

Spring Boot中使用Redis发布订阅功能并配置消息监听器容器

热心网友 时间:2026-07-22
转载

RedisMessageListenerContainer需手动声明为Bean,监听器必须实现MessageListener接口并通过addMessageListener()方法注册。为保证数据正确,序列化方式需与发布端完全一致,推荐统一使用StringRedisTemplate。发布端调用convertAndSend()发送消息时,需注意异常处理,例如添加

在 Spring Boot 中配置 Redis 发布订阅功能时,`RedisMessageListenerContainer` 必须手动声明为 Bean,Spring Boot 2.0 及以上版本不会自动完成该配置;监听器需要实现 `MessageListener` 接口,并通过 `addMessageListener()` 方法手工注册,不能依赖 `@EventListener` 注解;消息序列化策略必须与发布端保持一致,最稳妥的方式是统一使用 `StringRedisTemplate`。

如何在Spring Boot中使用Redis发布订阅功能_配置RedisMessageListenerContainer

RedisMessageListenerContainer 配置必须手动声明 Bean

Spring Boot 2.0 及更高版本默认不会自动创建 `RedisMessageListenerContainer` —— 即使你正确引入了 `spring-boot-starter-data-redis` 依赖,并且配置了 `RedisConnectionFactory`,容器也不会自动运行。如果不显式声明一个 Bean,那么 `@EventListener` 或你自定义的监听器类都不会被触发,订阅逻辑将静默失效。

一个典型的踩坑现象是:启动日志中看不到 “Starting RedisMessageListenerContainer” 这条信息,消息发布后监听器没有任何响应,也没有错误提示,仿佛消息石沉大海。

正确的做法很简单:手工声明一个 Bean,并确保它依赖已配置好的 `RedisConnectionFactory`:

@Bean
public RedisMessageListenerContainer redisMessageListenerContainer(
        RedisConnectionFactory connectionFactory) {
    RedisMessageListenerContainer container = new RedisMessageListenerContainer();
    container.setConnectionFactory(connectionFactory);
    container.setTaskExecutor(new ThreadPoolTaskExecutor()); // 避免阻塞主线程
    return container;
}

监听器注册要用 addMessageListener(),不是 @EventListener

Spring 的 `@EventListener` 注解仅适用于 Spring 自身的事件体系(`ApplicationEvent`),对 Redis 的发布/订阅消息完全无效。你必须通过 `RedisMessageListenerContainer.addMessageListener()` 方法将监听器实例显式注册到容器中。

一个常见的误区是:编写一个带有 `@Component` 和 `@EventListener` 的类,以为它能接收到 Redis 消息——实际上永远无法生效。

实操建议:

  • 监听器必须实现 `MessageListener` 接口(或者继承 `KeyExpirationEventMessageListener` 等子类)
  • 使用 `PatternTopic` 订阅通配符频道(例如 `PatternTopic("user:*")`),使用 `ChannelTopic` 订阅精确频道(例如 `ChannelTopic("user.login")`)
  • 注册时传入监听器实例和 Topic 列表,示例:`container.addMessageListener(myListener, new ChannelTopic("order.created"))`

消息序列化问题常导致 onMessage() 收到 null 或乱码

默认情况下,`RedisMessageListenerContainer` 使用 `JdkSerializationRedisSerializer`,但如果你的生产者端使用的是 `StringRedisTemplate`(即 `StringRedisSerializer`),两边的序列化方式就会不一致。`onMessage(Message, byte[])` 方法中 `message.getBody()` 获取到的内容可能是乱码,甚至为空字节数组。

解决方案需根据实际场景选择:

  • 统一使用 `StringRedisTemplate`:在配置容器时调用 `setTopicSerializer(new StringRedisSerializer())`(注意:该方法仅在 Spring Data Redis 2.6 及以上版本中可用)
  • 兼容老版本:自行实现 `MessageListener`,在 `onMessage()` 方法中手动解码:`new String(message.getBody(), StandardCharsets.UTF_8)`
  • 避免混用:不要使用 `RedisTemplate` 和 `StringRedisTemplate` 对同一组频道进行收发消息,否则会引发序列化冲突

发布端必须用 RedisTemplate 或 StringRedisTemplate 的 convertAndSend()

切勿使用 `execute()` 加原生 `PUBLISH` 命令绕过序列化逻辑,否则监听器收到的消息体无法正确反序列化——尤其是在容器配置了非默认序列化器的情况下。

正确的发布方式只有两种:

  • `redisTemplate.convertAndSend("channel.name", "hello")` —— 前提是 `redisTemplate` 的 value serializer 与监听器的解码方式一致
  • `stringRedisTemplate.convertAndSend("channel.name", "hello")` —— 最简洁可靠的方案,强烈推荐用于纯字符串消息

一个容易被忽略的细节:`convertAndSend()` 虽然是异步非阻塞的,但如果连接池耗尽或 Redis 服务宕机,它会抛出 `RedisConnectionFailureException`。因此外层最好捕获异常,不要天真地认为“消息发出去就一定能到达”。

来源:https://www.php.cn/faq/2802021.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
自增主键值从何而来?深入理解原理,告别只会auto_increment

自增主键值从何而来?深入理解原理,告别只会auto_increment

KingbaseES推荐使用serial、bigserial、显式sequence或identity列实现自增主键。serial创建integer并关联序列,bigserial对应bigint;显式sequence可自定义起始值等参数;identity有generatedbydefault(允许指定值)与always(禁止)两种模式。

时间:2026-07-25 22:22
Linux下瀚高数据库授权文件过期及替换解决方案

Linux下瀚高数据库授权文件过期及替换解决方案

在银河麒麟系统下,瀚高数据库hgdb-4 5试用授权20天到期后需替换正式授权文件。正确操作:停止服务,备份旧文件,将授权文件复制到 opt highgo hgdb-4 5 etc lic 并命名为hgdb lic,设置权限600和属主highgo:highgo,再启动服务。禁止直接修改data目录下的license info文件。

时间:2026-07-25 22:22
Oracle BLOB实时同步的5大技术挑战与难点解析

Oracle BLOB实时同步的5大技术挑战与难点解析

OracleBLOB实时同步面临分片组装、多列隔离、长事务跨窗口、事务回滚及大对象资源控制等技术挑战,必须在日志中精确还原完整字段值,才能保证源端与目标端数据完全一致,这对同步系统的稳健性提出了高要求。

时间:2026-07-25 22:22
MySQL禁用redo日志导致全备失败

MySQL禁用redo日志导致全备失败

MySQL全量备份失败是由于数据定义语言操作触发排序索引构建,禁用重做日志导致XtraBackup无法获取一致性备份。测试验证表明,优化表语句即使无数据也会触发该问题。根本原因在于排序索引构建过程跳过了重做日志记录,破坏了备份的一致性。

时间:2026-07-25 20:35
Kafka架构图优化与改进的全面详细步骤与实践指南

Kafka架构图优化与改进的全面详细步骤与实践指南

Kafka作为实时数据流处理的核心中间件,其底层架构虽已相当成熟,但在实际生产环境中,要充分发挥其性能潜力,仍需落实到具体的调优与架构改造上。核心目标可归纳为三点:如何承载更高的吞吐量、如何保障数据不丢失、以及故障发生时如何快速恢复。本文将从这几个关键方向出发,深入探讨如何真正榨干Kafka集群的性

时间:2026-07-25 20:35
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜