springboot 官方例子中文翻译--RabbitMQ 进行消息队列发布和订阅

本次我们讲述使用Springboot来操作 RabbitMQ 发布和订阅消息。消息队列在实际开发中经常用到,主要做了处理大规模数据,及模块解耦。而RabbitMQ是目前最热的消息队列之一,本例你可以学到RabbitMQ安装和使用。

我利用业余时间,翻译了Spring官网的例子,方便中文不好的同学,将陆续发到CSDN上,欢迎大家关注,也可以上我个人BLOG:itmanclub.com,上面有已经翻译过的。
在这里插入图片描述
正文:

** 程序结构**

└── 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将会你做如下的事:

  • 将 classpath 里面所有用到的jar包构建成一个可执行的 JAR 文件,方便执行你的程序
  • 搜索public static void main()方法并且将它当作可执行类
  • 根据springboot版本,去查找相应的依赖类版本,当然你可以定义其它版本。

** 创建一个RabbitMQ代理服务器**

在构建消息传递应用程序之前,需要设置处理接收和发送消息的Redis服务器。

RabbitMQ是AMQP服务器。服务器可从https://www.rabbitmq.com/download.html免费获得。

解包服务器并使用默认设置启动它。

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/rabbit@localhost.log
###### ## /usr/local/var/log/rabbitmq/rabbit@localhost-sasl.log
##########
 Starting broker... completed with 6 plugins.

如果有docker compose在本地运行,也可以使用docker compose快速启动RabbitMQ服务器。在Github的“complete”项目的根目录中有一个docker-compose.yml,配置很简单:

docker-compose.yml

rabbitmq:
 image: rabbitmq:management
 ports:
 - "5672:5672"
 - "15672:15672"

使用当前目录中的这个文件,您可以使RabbitMQ运行在docker compose容器中。

** 创建一个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;
 }
}

这个接收器是一个简单的POJO,它定义了接收消息的方法。当您注册它来接收消息时,您可以随意命名它。

为了方便起见,这个pojo还有一个CountDownLatch(倒计时)。这允许它发出信号来表明消息被接收了。在生产应用环境中,不用这样做的。

** 注册侦听器并发送消息**

Spring AMQP的RabbitTemplate提供了使用RabbitMQ发送和接收消息所需的一切。具体来说,您需要配置:

  • 消息侦听器容器
  • 声明队列、交换和它们之间的绑定
  • 用于发送一些消息以测试侦听器的组件
  • SpringBoot会自动创建一个连接工厂和一个RabbitTemplate,从而减少代码量。

您将使用RabbitTemplate发送消息,并且将在消息侦听器容器中注册一个接收者来接收消息。连接工厂类将驱动这两者,允许它们连接到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 告诉SpringBoot根据类路径设置、其他bean和各种属性设置开始添加bean。
  • @ComponentScan 告诉Spring在hello包中查找其他组件、配置和服务。

您注意到没有一行XML吗?也没有web.xml文件。这个Web应用程序是100%纯Java,您不必麻烦的基础配置。

listenerAdapter()方法中定义的bean在container()中定义的容器中被注册为消息侦听器。它将监听“spring-boot”队列中的消息。

因为receiver类是一个POJO,所以需要将其包装在MessageListenerAdapter中,并在其中指定它来调用receiveMessage。

JMS队列和AMQP队列具有不同的含义。例如,JMS只向一个使用者发送排队的消息。虽然AMQP队列执行相同的操作,但AMQP生产者不会直接向队列发送消息。

相反,消息被发送到一个交换区,那里可以通往一个队列,或者扇出到多个队列,从而模仿JMS主题的概念。有关更多信息,请参见AMQP信息。

消息侦听器容器和接收器bean都是来侦听消息的,要发送消息,还需要一个Rabbit模板。

queue()方法创建AMQP队列。exchange()方法创建主题交换。binding() 方法将这两个绑定在一起,定义当RabbitTemplate发布到交换时发生的行为。

Spring AMQP要求将队列、topiceExchange和绑定等声明为顶级Spring Beans,以便正确设置。

在这种情况下,我们使用主题交换、队列等绑定到路由键foo.bar.#,这意味着任何以foo.bar开头的消息将发送到队列。

** 发送测试信息**

测试消息由commandlinerunner发送,它还等待接收器中的latch并关闭应用程序上下文:

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,与绑定匹配。

测试中可以模拟出运行程序,这样就可以对接收器进行隔离测试。

** 运行你的程序(STS下,Maven可参考前面文章)**

你会看见如下的输出:

Sending message...
Received <Hello from RabbitMQ!>

您刚刚使用Spring和RabbitMQ开发了一个简单的发布和订阅应用程序。使用Spring和RabbitMQ可以做的比这里介绍的更多,但是这应该提供一个良好的开始。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值