本指南将引导您完成设置发布和订阅消息的RabbitMQ AMQP服务器的过程。
你会建立什么
您将使用Spring AMQP构建一个发布消息的应用程序RabbitTemplate
并使用订阅POJO上的消息MessageListenerAdapter
。
你需要什么
-
约15分钟
-
最喜欢的文本编辑器或IDE
-
JDK 1.8或更高版本
-
您还可以将代码直接导入到IDE中:
-
-
RabbitMQ服务器(下面的安装说明)
-
如何完成本指南
像大多数Spring 入门指南一样,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。无论哪种方式,您最终都可以使用工作代码。
要从头开始 ,请继续使用Gradle构建 。
要跳过基础知识 ,请执行以下操作:
-
下载并解压缩本指南的源存储库,或使用Git对其进行克隆:
git clone https://github.com/spring-guides/gs-messaging-rabbitmq.git
-
光盘进入
gs-messaging-rabbitmq/initial
完成后 ,您可以根据中的代码检查结果gs-messaging-rabbitmq/complete
。
用Gradle构建
用Gradle构建
首先,您设置一个基本的构建脚本。在使用Spring构建应用程序时,可以使用任何喜欢的构建系统,但是此处包含使用Gradle和Maven所需的代码。如果您都不熟悉,请参阅使用Gradle 构建Java项目或使用Maven构建Java项目 。
创建目录结构
在您选择的项目目录中,创建以下子目录结构;例如, mkdir -p src/main/java/hello
在* nix系统上:
└── src └── main └── java └── hello
创建一个Gradle构建文件
以下是最初的Gradle构建文件 。
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:2.1.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
bootJar {
baseName = 'gs-messaging-rabbitmq'
version = '0.1.0'
}
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile("org.springframework.boot:spring-boot-starter-amqp")
testCompile("junit:junit")
}
Spring Boot gradle插件提供了许多方便的功能:
-
它收集类路径上的所有jar,并构建一个可运行的单个“über-jar”,这使执行和传输服务更加方便。
-
它搜索
public static void main()
标记为可运行类的方法。 -
它提供了一个内置的依赖项解析器,用于设置版本号以匹配Spring Boot依赖项 。您可以覆盖所需的任何版本,但是它将默认为Boot选择的一组版本。
用Maven构建
用Maven构建
创建目录结构
在您选择的项目目录中,创建以下子目录结构;例如, mkdir -p src/main/java/hello
在* nix系统上:
└── src └── main └── java └── hello
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>
<groupId>org.springframework</groupId>
<artifactId>gs-messaging-rabbitmq</artifactId>
<version>0.1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Spring Boot Maven插件提供了许多方便的功能:
-
它收集类路径上的所有jar,并构建一个可运行的单个“über-jar”,这使执行和传输服务更加方便。
-
它搜索
public static void main()
标记为可运行类的方法。 -
它提供了一个内置的依赖项解析器,用于设置版本号以匹配Spring Boot依赖项 。您可以覆盖所需的任何版本,但是它将默认为Boot选择的一组版本。
使用您的IDE进行构建
使用您的IDE进行构建
-
阅读如何将本指南直接导入Spring Tool Suite中 。
-
在IntelliJ IDEA中阅读如何使用本指南。
设置RabbitMQ经纪人
在构建消息传递应用程序之前,您需要设置将处理接收和发送消息的服务器。
RabbitMQ是AMQP服务器。该服务器可从https://www.rabbitmq.com/download.html免费获得。您可以手动下载它,或者如果您使用带有自制软件的Mac:
brew install rabbitmq
打开服务器包装,并使用默认设置启动它。
rabbitmq-server
您应该会看到以下内容:
RabbitMQ 3.1.3. Copyright (C) 2007-2013 VMware, Inc. ## ## Licensed under the MPL. See https://www.rabbitmq.com/ ## ## ########## Logs: /usr/local/var/log/rabbitmq/[email protected] ###### ## /usr/local/var/log/rabbitmq/[email protected] ########## Starting broker... completed with 6 plugins.
如果您在本地运行docker,也可以使用Docker Compose快速启动RabbitMQ服务器。有一个docker-compose.yml
在Github中“完整”项目的根目录中。这很简单:
docker-compose.yml
rabbitmq:
image: rabbitmq:management
ports:
- "5672:5672"
- "15672:15672"
使用此文件在当前目录中,您可以运行docker-compose up
使RabbitMQ在容器中运行。
创建RabbitMQ消息接收器
对于任何基于消息传递的应用程序,您需要创建一个接收器,该接收器将响应已发布的消息。
src/main/java/hello/Receiver.java
package hello;
import java.util.concurrent.CountDownLatch;
import org.springframework.stereotype.Component;
@Component
public class Receiver {
private CountDownLatch latch = new CountDownLatch(1);
public void receiveMessage(String message) {
System.out.println("Received <" + message + ">");
latch.countDown();
}
public CountDownLatch getLatch() {
return latch;
}
}
的Receiver
是一个简单的POJO,它定义了一种接收消息的方法。注册它以接收消息时,可以随意命名。
为方便起见,此POJO还具有一个CountDownLatch 。这使其可以发出已接收到该消息的信号。这是您不太可能在生产应用程序中实现的东西。 |
注册侦听器并发送消息
Spring AMQP RabbitTemplate
提供使用RabbitMQ发送和接收消息所需的一切。具体来说,您需要配置:
-
消息侦听器容器
-
声明队列,交换以及它们之间的绑定
-
发送一些消息以测试侦听器的组件
Spring Boot自动创建一个连接工厂和一个RabbitTemplate,从而减少了您必须编写的代码量。 |
您将使用RabbitTemplate
发送消息,您将注册一个Receiver
与消息侦听器容器一起接收消息。连接工厂驱动两者,从而允许它们连接到RabbitMQ服务器。
src/main/java/hello/Application.java
package hello;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class Application {
static final String topicExchangeName = "spring-boot-exchange";
static final String queueName = "spring-boot";
@Bean
Queue queue() {
return new Queue(queueName, false);
}
@Bean
TopicExchange exchange() {
return new TopicExchange(topicExchangeName);
}
@Bean
Binding binding(Queue queue, TopicExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with("foo.bar.#");
}
@Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queueName);
container.setMessageListener(listenerAdapter);
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(Receiver receiver) {
return new MessageListenerAdapter(receiver, "receiveMessage");
}
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(Application.class, args).close();
}
}
@SpringBootApplication
是一个方便注释,它添加了以下所有内容:
-
@Configuration
:将类标记为应用程序上下文的Bean定义的源。 -
@EnableAutoConfiguration
:告诉Spring Boot根据类路径设置,其他bean和各种属性设置开始添加bean。例如,如果spring-webmvc
在类路径上,此注释将应用程序标记为Web应用程序并激活关键行为,例如设置DispatcherServlet
。 -
@ComponentScan
:告诉Spring在其中寻找其他组件,配置和服务hello
包,让它找到控制器。
的main()
方法使用Spring Boot的SpringApplication.run()
启动应用程序的方法。您是否注意到没有一行XML?没有web.xml
文件。该Web应用程序是100%纯Java,因此您无需处理任何管道或基础结构。
在中定义的bean listenerAdapter()
方法已在中定义的容器中注册为消息侦听器container()
。它将在“ spring-boot”队列上侦听消息。因为Receiver
类是一个POJO,需要包装在MessageListenerAdapter
,在其中指定要调用的位置receiveMessage
。
JMS队列和AMQP队列具有不同的语义。例如,JMS仅将排队的消息发送给一个使用者。尽管AMQP队列执行相同的操作,但AMQP生产者不会将消息直接发送到队列。而是将消息发送到交换机,该交换机可以转到单个队列,也可以扇出到多个队列,以模拟JMS主题的概念。有关更多信息,请参阅了解AMQP 。 |
消息侦听器容器和接收者Bean就是您侦听消息所需的全部。要发送消息,您还需要Rabbit模板。
的queue()
方法创建一个AMQP队列。的exchange()
方法创建主题交流。的binding()
方法将这两者绑定在一起,定义当RabbitTemplate发布到交易所时发生的行为。
Spring AMQP要求Queue , TopicExchange 和Binding 被声明为顶级Spring Bean,以便正确设置。 |
在这种情况下,我们使用主题交换,并且队列与路由键绑定foo.bar.#
这意味着任何以路由键开头的消息都以foo.bar.
将被路由到队列。
发送测试信息
测试消息由CommandLineRunner
,它还会等待接收器中的闩锁并关闭应用程序上下文:
src/main/java/hello/Runner.java
package hello;
import java.util.concurrent.TimeUnit;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class Runner implements CommandLineRunner {
private final RabbitTemplate rabbitTemplate;
private final Receiver receiver;
public Runner(Receiver receiver, RabbitTemplate rabbitTemplate) {
this.receiver = receiver;
this.rabbitTemplate = rabbitTemplate;
}
@Override
public void run(String... args) throws Exception {
System.out.println("Sending message...");
rabbitTemplate.convertAndSend(Application.topicExchangeName, "foo.bar.baz", "Hello from RabbitMQ!");
receiver.getLatch().await(10000, TimeUnit.MILLISECONDS);
}
}
请注意,模板使用以下路由键将消息路由到交换机foo.bar.baz
匹配绑定。
可以在测试中模拟流道,以便可以单独测试接收器。
运行应用程序
的main()
方法通过创建Spring应用程序上下文来启动该过程。这将启动消息侦听器容器,该容器将开始侦听消息。有一个Runner
然后自动执行的bean:它检索RabbitTemplate
从应用程序上下文中发送一个“来自RabbitMQ的问候!“ spring-boot”队列中的消息。最后,它关闭Spring应用程序上下文并结束应用程序。
构建可执行的JAR
您可以使用Gradle或Maven从命令行运行该应用程序。您还可以构建一个包含所有必需的依赖项,类和资源的可执行JAR文件,然后运行该文件。构建可执行的jar使得在整个开发生命周期中,跨不同环境等等的情况下,可以轻松地将服务作为应用程序进行发布,版本化和部署。
如果您使用Gradle,则可以使用./gradlew bootRun
。或者,您可以通过使用以下命令构建JAR文件: ./gradlew build
然后运行JAR文件,如下所示:
如果使用Maven,则可以通过使用以下命令运行应用程序./mvnw spring-boot:run
。或者,您可以使用以下命令构建JAR文件: ./mvnw clean package
然后运行JAR文件,如下所示:
此处描述的步骤将创建可运行的JAR。您还可以构建经典的WAR文件 。 |
您应该看到以下输出:
Sending message... Received <Hello from RabbitMQ!>
摘要
恭喜你!您刚刚使用Spring和RabbitMQ开发了一个简单的发布和订阅应用程序。 使用Spring和RabbitMQ可以做的比这里介绍的要多,但这应该是一个很好的开始。
也可以看看
以下指南也可能会有所帮助:
是否要编写新指南或为现有指南做出贡献?查看我们的贡献准则 。
所有指南均以代码的ASLv2许可证和写作的Attribution,NoDerivatives创作共用许可证发布 。 |