Spring Boot入门教程:第七章:使用Redis进行消息传递

本章带你使用Spring Data Redis实现发布和订阅Redis的消息。

本文目标

用Spring Boot构建一个应用,使用StringRedisTemplate发布一个字符串消息,使用MessageListenerAdapter订阅消息。

使用Spring Data Redis发布消息听起来有点奇怪,但是你会发现,Redis不仅提供了一个NoSQL数据存储,还有一个消息系统。

你需要

  • 15分钟左右
  • IntelliJ IDEA
  • JDK 1.8+
  • Maven 3.2+
  • Redis服务器

启动一个Redis服务器

在创建一个消息应用之前,我们需要配置一个负责接收信息和发送信息的服务器。

Redis是一个开源,基于BSD协议,key-value存储系统,附带一个消息系统。

Windows版的安装方法可以参照这篇文章Redis下载及安装(windows版).

用Spring Initializr生成项目代码

对于所有的Spring应用,你都可以使用Spring Initializr生成基本的项目代码。Initializr提供了一个快速的方式去引入所有你需要的依赖,并且为你做了很多设置。当前例子需要 Spring Data Redis依赖。

具体设置如下图:
在这里插入图片描述

如上图所示,我们选择了Maven作为编译工具。你也可以选择Gradle来进行编译。然后我们分别把Group和Artifact设置为“com.hansy”和“messaging-redis”。

生成的pom.xml文件内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.hansy</groupId>
	<artifactId>messaging-redis</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>messaging-redis</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

创建一个Redis消息接收器

在任何的基于消息的应用中,都有消息的发布者和消息的接受者。实现一个消息接收器,拥有一个可以响应消息的方法。代码如下:

package com.hansy.messagingredis;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.atomic.AtomicInteger;

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

    private AtomicInteger counter = new AtomicInteger();

    public void receiveMessage(String message) {
    
    
        logger.info("Received <" + message + ">");
        counter.incrementAndGet();
    }

    public int getCount() {
    
    
        return counter.get();
    }
}

Receiver是一个定义了接收接收消息的方法的POJO类。当你注册了一个Receiver作为消息监听器的话,消息处理方法的命名可以随意。

为了演示目的,这个Receiver只是对接收到的消息进行计数。

注册监听器和发送消息

Spring Data Redis提供了使用Redis来发送和接收消息的所有组件。

我们需要配置如下元素:

  • 一个连接工厂
  • 一个消息监听器的容器
  • 一个Redis的Template

我们将会使用Redis的Template来发送消息,注册Receiver到消息监听器的容器来接收消息。连接工厂驱动Template和消息监听器的容器,让他们连接到Redis服务器。

本例使用了Spring Boot默认的RedisConnectionFactory,一个JedisConnectionFactory(基于jedis库)的实例。这个连接工厂注入了消息监听器的容器和Redis的Template,代码如下:

package com.hansy.messagingredis;

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;

@SpringBootApplication
public class MessagingRedisApplication {
    
    

    private static final Logger logger = LoggerFactory.getLogger(MessagingRedisApplication.class);

    @Bean
    Receiver receiver() {
    
    
        return new Receiver();
    }

    @Bean
    MessageListenerAdapter listenerAdapter(Receiver receiver) {
    
    
        return new MessageListenerAdapter(receiver, "receiveMessage");
    }

    @Bean
    RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
                                            MessageListenerAdapter listenerAdapter) {
    
    
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory);
        container.addMessageListener(listenerAdapter, new PatternTopic("chat"));

        return container;
    }

    @Bean
    StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
    
    
        return new StringRedisTemplate(connectionFactory);
    }

    public static void main(String[] args) throws InterruptedException {
    
    
        ApplicationContext context = SpringApplication.run(MessagingRedisApplication.class, args);
        StringRedisTemplate template = context.getBean(StringRedisTemplate.class);
        Receiver receiver = context.getBean(Receiver.class);

        while (receiver.getCount() == 0) {
    
    
            logger.info("Sending message...");
            template.convertAndSend("chat", "Hello from Redis!");
            Thread.sleep(500L);
        }

        System.exit(0);
    }

}

receiver()方法返回一个简单的Receiver对象,这个Receiver对象会被包装到listenerAdapter()方法返回的MessageListenerAdapter里面。再通过addMessageListener()方法添加到RedisMessageListenerContainer里面,对“chat”主题进行监听。当消息到达时,会调用Receiver对象的receiveMessage()方法。

监听消息需要连接工厂和消息监听容器等一些类。而发送消息,则需要RedisTemplate。我们使用了RedisTemplate的一个实现类StringRedisTemplate,使用Redis时,key和value都是String实例。

main()方法首先创建一个SpringApplication上下文。然后Application上下文启动一个消息监听容器,而消息监听容器开始监听消息。main()方法接着从上下文中取出一个StringRedisTemplate对象,然后用StringRedisTemplate在“chat”主题上发送一条文字消息“Hello from Redis!”。最后,关闭SpringApplication上下文,程序结束。

运行程序

运行程序,结果如下:

2020-07-30 16:45:15.548  INFO 24544 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2020-07-30 16:45:15.550  INFO 24544 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2020-07-30 16:45:15.576  INFO 24544 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 10ms. Found 0 Redis repository interfaces.
2020-07-30 16:45:18.077  INFO 24544 --- [           main] c.h.m.MessagingRedisApplication          : Started MessagingRedisApplication in 3.157 seconds (JVM running for 6.317)
2020-07-30 16:45:18.079  INFO 24544 --- [           main] c.h.m.MessagingRedisApplication          : Sending message...
2020-07-30 16:45:18.092  INFO 24544 --- [    container-2] com.hansy.messagingredis.Receiver        : Received <Hello from Redis!>

小结

你已经用Spring Boot开发了一个使用Redis完成发布与订阅的程序。

源码下载

messaging-redis

参考资料

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

猜你喜欢

转载自blog.csdn.net/hanshiying007/article/details/107579278