SpringBoot集成Redis消息订阅发布

本文介绍如何在SpringBoot项目中集成Redis实现消息订阅与发布功能。通过添加依赖、创建消息接收器及配置监听器完成集成流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SpringBoot集成Redis消息订阅发布

1. pom.xml文件添加依赖
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. 创建一个Redis消息接收器
package cn.tyrone.springboot.redis.message;

import java.util.concurrent.CountDownLatch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

public class Receiver {
	private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class);

	private CountDownLatch latch;

	@Autowired
	public Receiver(CountDownLatch latch) {
		this.latch = latch;
	}

	public void receiveMessage(String message) {
		LOGGER.info("Received <" + message + ">");
		latch.countDown();
	}
}

Receiver这是一个定义了一个接收消息的方法的类。当你把这个类作为一个消息监听器来注册后,你可以自定义消息接收的方法名。本例中采用“receiveMessage”作为接收消息的方法。

3. 注册一个监听器并发送消息

Spring Data Redis 提供了使用Redis发送和接收的消息的所有的组件。我们只需要做以下配置:

  • 一个Redis连接工厂(A connection factory)
  • 一个消息监听器的容器(A message listener container)
  • 一个Redis模板(A redis template)

我们使用redis template发送消息,把Receiver类注册为一个消息监听器以使它可以接收消息。Connection factory是授权它们连接Redis服务的。
本例中采用的是SpringBoot默认的RedisConnectionFactory,这是一个基于jedis Redis库的JedisConnectionFactory的实例。它被注入到消息监听器和redis模板中。

编写SpringBoot启动类并注入本例需要的对象实例

package cn.tyrone.springboot.redis.message;

import java.util.concurrent.CountDownLatch;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;

//https://spring.io/guides/gs/messaging-redis/

@SpringBootApplication
public class Application {
	public static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
	
	/*
	 * Redis消息监听器容器
	 * 这个容器加载了RedisConnectionFactory和消息监听器
	 */
	@Bean
	RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, 
			MessageListenerAdapter listenerAdapter){
		RedisMessageListenerContainer container = new RedisMessageListenerContainer();
		container.setConnectionFactory(connectionFactory);
		container.addMessageListener(listenerAdapter, new PatternTopic("sprinboot-redis-messaage"));
		return container;
	}
	
	/*
	 * 将Receiver注册为一个消息监听器,并指定消息接收的方法(receiveMessage)
	 * 如果不指定消息接收的方法,消息监听器会默认的寻找Receiver中的handleMessage这个方法作为消息接收的方法
	 */
	@Bean
	MessageListenerAdapter listenerAdapter(Receiver receiver){
		return new MessageListenerAdapter(receiver, "receiveMessage");
	}
	
	/*
	 * Receiver实例
	 */
	@Bean
	Receiver receiver(CountDownLatch latch){
		return new Receiver(latch);
	}
	
	@Bean
	CountDownLatch latch(){
		return new CountDownLatch(1);
	}
	
	/*
	 * Redis Template 用来发送消息
	 */
	@Bean
	StringRedisTemplate template(RedisConnectionFactory connectionFactory){
		return new StringRedisTemplate(connectionFactory);
	}
	
	/*
	 * 测试用例
	 */
	public static void main(String[] args) throws Exception {
		ApplicationContext ctx = SpringApplication.run(Application.class, args);
		
		StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class);
//		CountDownLatch latch = ctx.getBean(CountDownLatch.class);
		
		LOGGER.info("Sending message......");
		template.convertAndSend("sprinboot-redis-messaage", "Hello, SpringBoot redis message!!!!");
//		latch.wait();
		
		System.exit(0);
		
	}
	
}

对于本例并不十分清楚CountDownLatch latch这个的目的,在测试的过程中,加上这句代码,会抛一个异常,但是发送和接收消息都是成功的。异常信息如下:

2017-07-20 10:14:50.909  INFO 7200 --- [           main] c.t.s.redis.message.Application          : Sending message......
Exception in thread "main" java.lang.IllegalMonitorStateException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:502)
	at cn.tyrone.springboot.redis.message.Application.main(Application.java:77)

如果将此代码注释掉,该异常也将消息。同时,也并不影响消息的发布与接收。CountDownLatch 只是一个同步的辅助类,测试过程中,并没有发现这个类对测试结果的有什么帮助。

参考链接:https://spring.io/guides/gs/messaging-redis/
源代码链接:https://github.com/myNameIssls/springboot-study

<think>好的,用户想在Spring Boot中集成Redis实现发布订阅功能。首先,我需要回忆一下Spring Data Redis的相关知识。记得Redis发布订阅模式需要配置消息监听容器和消息监听器。用户可能需要具体的代码示例和配置步骤。 首先,应该从添加依赖开始,比如Spring Boot Starter Data Redis。然后配置Redis连接信息,比如主机、端口、密码等,这些通常在application.properties里设置。接下来,需要定义消息监听容器和适配器,可能使用RedisMessageListenerContainer和ChannelTopic。 然后,用户需要创建发布消息的服务,使用RedisTemplate的convertAndSend方法。订阅方面,需要实现MessageListener接口或者使用注解@RedisListener,不过Spring Data Redis好像没有这个注解,可能需要通过配置监听容器来添加订阅的频道。 还需要考虑多线程消费的问题,参考用户提供的引用链接中有提到多线程消费和线程池配置,可能需要设置TaskExecutor来并行处理消息。另外,序列化方式也很重要,默认的JDK序列化可能不友好,建议使用StringRedisSerializer或者JSON序列化。 用户可能还会遇到频道通配符的问题,比如使用PSUBSCRIBE来订阅模式匹配的频道,这时候可能需要使用PatternTopic代替ChannelTopic。另外,异常处理也是需要注意的地方,比如连接失败时的处理机制。 需要检查用户提供的引用链接,特别是优快云和Stack Overflow的那些,看看有没有最佳实践或常见问题解答。例如,某个链接提到并行消费和线程池配置,这可能涉及到调整监听容器的并发设置。另一个链接讨论了多主题订阅,可能需要配置多个消息监听器或使用通配符。 总结下来,步骤大致是:添加依赖、配置连接、设置消息监听容器、实现监听器、创建发布服务,以及考虑序列化和并发处理。在回答中需要提供代码示例,确保LaTeX格式正确,同时生成相关问题引导用户进一步学习。</think>### Spring Boot集成Redis发布订阅功能分步指南 #### 一、环境准备 1. 添加Maven依赖(Spring Boot 2.7.x) ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> ``` 2. 配置application.yml ```yaml spring: redis: host: localhost port: 6379 password: yourpassword lettuce: pool: max-active: 8 max-idle: 8 min-idle: 0 ``` #### 二、核心配置类 ```java @Configuration @EnableCaching public class RedisConfig { @Bean public RedisMessageListenerContainer redisContainer(RedisConnectionFactory factory, MessageListenerAdapter listenerAdapter) { RedisMessageListenerContainer container = new RedisMessageListenerContainer(); container.setConnectionFactory(factory); container.addMessageListener(listenerAdapter, new ChannelTopic("news_channel")); container.setTaskExecutor(taskExecutor()); // 设置线程池[^2] return container; } @Bean public TaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.setMaxPoolSize(10); executor.setQueueCapacity(25); return executor; } @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; } } ``` #### 三、消息监听器实现 ```java @Component public class NewsSubscriber implements MessageListener { private static final Logger logger = LoggerFactory.getLogger(NewsSubscriber.class); @Override public void onMessage(Message message, byte[] pattern) { String channel = new String(message.getChannel()); String body = new String(message.getBody()); logger.info("Received [{}] from [{}]", body, channel); } } ``` #### 四、消息发布服务 ```java @Service public class NewsPublisher { private final RedisTemplate<String, Object> redisTemplate; @Autowired public NewsPublisher(RedisTemplate<String, Object> redisTemplate) { this.redisTemplate = redisTemplate; } public void publishNews(String message) { redisTemplate.convertAndSend("news_channel", message); } } ``` #### 五、使用示例 ```java @RestController @RequestMapping("/news") public class NewsController { private final NewsPublisher publisher; @Autowired public NewsController(NewsPublisher publisher) { this.publisher = publisher; } @PostMapping public ResponseEntity<String> postNews(@RequestBody String content) { publisher.publishNews(content); return ResponseEntity.ok("Message published"); } } ``` #### 高级特性配置 1. **通配符订阅**: ```java // 在RedisConfig中添加 container.addMessageListener(listenerAdapter, new PatternTopic("sensor.*")); ``` 2. **消息序列化优化**: ```java // 配置专用String模板 @Bean public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(factory); template.setValueSerializer(new GenericToStringSerializer<>(String.class)); return template; } ``` #### 常见问题排查 1. 消息未接收:检查`@Bean`注入顺序和频道名称一致性 2. 序列化异常:确保发布/订阅端使用相同序列化方式 3. 连接超时:验证防火墙设置和Redis服务状态
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值