SpringBoot Redis 消息传输

开篇词

该指南将引导你完成使用 Spring Data Redis 发布和订阅 Redis 所发的消息。
 

你将创建的应用

我们将构建一个应用,该应用借助 SpringRedisTemplate 发布字符串消息,并通过 MessageListenerAdapter 使 POJO 订阅该消息。
 

你将需要的工具

如何完成这个指南

像大多数的 Spring 入门指南一样,你可以从头开始并完成每个步骤,也可以绕过你已经熟悉的基本设置步骤。如论哪种方式,你最终都有可以工作的代码。

  • 要从头开始,移步至启动一个 Redis 服务器
  • 要跳过基础,执行以下操作:
    • 下载并解压缩该指南将用到的源代码,或借助 Git 来对其进行克隆操作:git clone https://github.com/spring-guides/gs-messaging-redis.git
    • 切换至 gs-messaging-redis/initial 目录;
    • 或跳转至该指南的从 Spring Initializr 开始

待一切就绪后,可以检查一下 gs-messaging-redis/complete 目录中的代码。

启动一个 Redis 服务器

在构建消息传递应用之前,我们需要配置处理接收和发送消息的服务器。

Redis 是一款开源的,BSD 许可的键值数据存储,还附带了消息传递系统。该服务器可从 https://redis.io/download 免费获得。我们可以手动下载它,或如果使用 Mac,则可以通过 Homebrew 来进行下载,方法是在终端窗口中运行以下命令:

brew install redis

解包 Redis 之后,可以通过运行以下命令以默认配置来启动它:

redis-server

我们应该看到类似于以下内容的消息:

[35142] 01 May 14:36:28.939 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
[35142] 01 May 14:36:28.940 * Max number of open files set to 10032
                _._
              _.-``__ ''-._
        _.-``    `.  `_.  ''-._           Redis 2.6.12 (00000000/0) 64 bit
    .-`` .-```.  ```\/    _.,_ ''-._
  (    '      ,       .-`  | `,    )     Running in stand alone mode
  |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
  |    `-._   `._    /     _.-'    |     PID: 35142
    `-._    `-._  `-./  _.-'    _.-'
  |`-._`-._    `-.__.-'    _.-'_.-'|
  |    `-._`-._        _.-'_.-'    |           https://redis.io
    `-._    `-._`-.__.-'_.-'    _.-'
  |`-._`-._    `-.__.-'    _.-'_.-'|
  |    `-._`-._        _.-'_.-'    |
    `-._    `-._`-.__.-'_.-'    _.-'
        `-._    `-.__.-'    _.-'
            `-._        _.-'
                `-.__.-'

[35142] 01 May 14:36:28.941 # Server started, Redis version 2.6.12
[35142] 01 May 14:36:28.941 * The server is now ready to accept connections on port 6379

从 Spring Initializr 开始

对于所有的 Spring 应用来说,你应该从 Spring Initializr 开始。Initializr 提供了一种快速的方法来提取应用程序所需的依赖,并为你完成许多设置。该示例仅需要 Spring for Redis 依赖。下图显示了此示例项目的 Initializr 设置:
Spring Initializr 界面

上图显示了选择 Maven 作为构建工具的 Initializr。你也可以使用 Gradle。它还将 com.examplemessaging-redis 的值分别显示为 Group 和 Artifact。在本示例的其余部分,将用到这些值。

以下清单显示了选择 Maven 时创建的 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.2.2.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</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>

以下清单显示了在选择 Gradle 时创建的 build.gradle 文件:

plugins {
	id 'org.springframework.boot' version '2.2.2.RELEASE'
	id 'io.spring.dependency-management' version '1.0.8.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-redis'
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
	}
}

test {
	useJUnitPlatform()
}

创建一个 Redis 消息接收者

在任何基于消息的应用中,都有消息发布者和消息接收者。要创建消息接收者,请使用一种响应消息的方法来实现接收者,如以下示例(来自 src/main/java/com/example/messagingredis/Receiver.java)所示:

package com.example.messagingredis;

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 是一个 POJO,它定义了一种接收消息的方法。在将 Receiver 注册为消息监听器时,可以根据需要来命名消息处理方法。

出于演示目的,接收者由其构造函数与倒计时闩锁自动连线。这样,它可以在收到消息时发出信号。

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

Spring Data Redis 提供了使用 Redis 发送和接收消息所需的所有组件。具体来说,我们需要配置:

  • 连接工厂
  • 消息监听器容器
  • Redis 模版

我们将使用 Redis 模版发送消息,并在消息监听器容器中注册 Receiver,以便它能接收消息。连接工厂将同时驱动模版以及消息监听器容器,从而使它们连接到 Redis 服务器。

该示例使用 Spring Boot 的默认 RedisConnectionFactory,这是一个基于 Jedis Redis 库的 JedisConnectionFactory 实例。连接工厂被注入到消息监听器容器以及 Redis 模版中,如以下示例(来自 src/main/java/com/example/messagingredis/MessagingRedisApplication.java)所示:

package com.example.messagingredis;

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;

@SpringBootApplication
public class MessagingRedisApplication {

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

	@Bean
	RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,
			MessageListenerAdapter listenerAdapter) {

		RedisMessageListenerContainer container = new RedisMessageListenerContainer();
		container.setConnectionFactory(connectionFactory);
		container.addMessageListener(listenerAdapter, new PatternTopic("chat"));

		return container;
	}

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

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

	@Bean
	CountDownLatch latch() {
		return new CountDownLatch(1);
	}

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

	public static void main(String[] args) throws InterruptedException {

		ApplicationContext ctx = SpringApplication.run(MessagingRedisApplication.class, args);

		StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class);
		CountDownLatch latch = ctx.getBean(CountDownLatch.class);

		LOGGER.info("Sending message...");
		template.convertAndSend("chat", "Hello from Redis!");

		latch.await();

		System.exit(0);
	}
}

listenerAdapter 方法中定义的 Bean 在 container 中定义的消息监听器容器中注册为消息监听器,并将监听 chat 主题中的消息。由于 Receiver 类是 POJO,因此需要将其包装在实现 MessageListener 接口的消息监听器适配器中(addMessageListener() 所需的)。消息监听器适配器还配置了在消息到达时在 Receiver 上调用 receiveMessage() 方法。

我们只需要连接工厂和消息监听器容器 Bean 即可监听消息。要发送消息,我们还需要一个 Redis 模版。在这里,它是一个被配置为 StringRedisTemplate 的 bean,这是 RedisTemplate 的实现,重点是 Redis 的常用用法,其中键和值都是 String 实例。

main() 方法通过创建 Spring 应用上下文开始所有工作。然后,应用上下文启动消息监听器容器,并且消息监听器容器 Bean 开始监听消息。接下来,main() 方法从应用上下文中检索 StringRedisTemplate 的 bean,并使用它来发送有关 chat 主题的消息 Hello from Redis!。最后,它关闭 Spring 应用上下文,然后应用结束。
 

运行应用

我们可以结合 Gradle 或 Maven 来从命令行运行该应用。我们还可以构建一个包含所有必须依赖项、类以及资源的可执行 JAR 文件,然后运行该文件。在整个开发生命周期中,跨环境等等情况下,构建可执行 JAR 可以轻松地将服务作为应用进行发布、版本化以及部署。

如果使用 Gradle,则可以借助 ./gradlew bootRun 来运行应用。或通过借助 ./gradlew build 来构建 JAR 文件,然后运行 JAR 文件,如下所示:

java -jar build/libs/gs-messaging-redis-0.1.0.jar

如果使用 Maven,则可以借助 ./mvnw spring-boot:run 来运行该用。或可以借助 ./mvnw clean package 来构建 JAR 文件,然后运行 JAR 文件,如下所示:

java -jar target/gs-messaging-redis-0.1.0.jar

我们还可以构建一个经典的 WAR 文件

我们应该看到以下输出:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.1.8.RELEASE)

2019-09-23 12:57:11.578  INFO 35396 --- [           main] c.e.m.MessagingRedisApplication          : Starting MessagingRedisApplication on Jays-MBP with PID 35396 (/Users/j/projects/guides/gs-messaging-redis/complete/target/classes started by j in /Users/j/projects/guides/gs-messaging-redis/complete)
2019-09-23 12:57:11.581  INFO 35396 --- [           main] c.e.m.MessagingRedisApplication          : No active profile set, falling back to default profiles: default
2019-09-23 12:57:11.885  INFO 35396 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2019-09-23 12:57:11.887  INFO 35396 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode.
2019-09-23 12:57:11.914  INFO 35396 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 13ms. Found 0 repository interfaces.
2019-09-23 12:57:12.685  INFO 35396 --- [    container-1] io.lettuce.core.EpollProvider            : Starting without optional epoll library
2019-09-23 12:57:12.685  INFO 35396 --- [    container-1] io.lettuce.core.KqueueProvider           : Starting without optional kqueue library
2019-09-23 12:57:12.848  INFO 35396 --- [           main] c.e.m.MessagingRedisApplication          : Started MessagingRedisApplication in 1.511 seconds (JVM running for 3.685)
2019-09-23 12:57:12.849  INFO 35396 --- [           main] c.e.m.MessagingRedisApplication          : Sending message...
2019-09-23 12:57:12.861  INFO 35396 --- [    container-2] com.example.messagingredis.Receiver      : Received <Hello from Redis!>

概述

恭喜你!我们刚刚使用 Spring 结合 Redis 开发了一个发布订阅的应用。

Redis 支持可用

参见

以下指南也可能会有所帮助:

想看指南的其他内容?请访问该指南的所属专栏:《Spring 官方指南

发布了103 篇原创文章 · 获赞 6 · 访问量 5074

猜你喜欢

转载自blog.csdn.net/stevenchen1989/article/details/104091027