译Spring官方教程:Spring Boot整合消息中间件RabbitMQ

Posted SpringForAll社区

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了译Spring官方教程:Spring Boot整合消息中间件RabbitMQ相关的知识,希望对你有一定的参考价值。

Spring Boot整合消息中间件RabbitMQ

原文:Messaging with RabbitMQ

译者:chenzhijun

校对:程序猿DD

本篇指南会告诉您如何使用构建一个基于 AMQP协议的 RabbitMQ 服务,并且教您如何实现发布和订阅消息。

你会得到什么?

你会创建一个应用,它能够使用 Spring AMQP 的 RabbitTemplate发布消息,并且通过使用 MessageListenerAdapter包装一个 POJO 来接受消息。

你需要准备什么?

  • 大概15分钟时间

  • 一个喜欢的文本编辑器或者IDE

  • JDK 1.8 or 更高版本 *Gradle 2.3+ or Maven 3.0+

  • 你可以直接导入 RabbitMQ 服务的代码到 IDE : Spring Tool Suite (STS) 或者 IntelliJ IDEA (点击进入安装步骤)

怎样完成指南?

像大多数 Spring 教程指南一样,你可以选择从最基础开始,一步步的完成 Demo ,或者你也可以绕过你熟悉的步骤再开始。不管哪种方式,你最后都会得到一份可执行的代码。

如果从基础开始,你可以往下查看怎样使用 Gradle 构建项目。

如果已经熟悉一些基本步骤,你可以:

  • 下载并解压源码库 ,或者通过 Git 工具克隆一份代码:了解Git : git clone[https://github.com/spring-guides/gs-messaging-rabbitmq.git]

  • cd into gs-messaging-rabbitmq/initial

  • 往下看 创建RabbitMQ 消息接收者

当你完成之后,你可以在 gs-messaging-rabbitmq/complete检查下结果。

使用 Gradle 构建项目

首先你需要编写基础构建脚本。在构建 Spring 应用的时候,你可以使用任何你喜欢的系统来构建,这里提供一份你可能需要用 Gradle 或者 Maven 构建的代码。如果你对两者都不是很熟悉,你可以先去看下如何使用 Gradle 构建 Java 项目或者如何使用 Maven 构建 Java 项目。

创建 Gradle 目录结构

在你的项目根目录,创建如下的子目录结构;例如,如果你使用的是 *nix系统,你可以使用 mkdir-p src/main/java/hello

 
   
   
 
  1. └── src

  2.    └── main

  3.        └── java

  4.            └── hello

创建 Gradle 构建文件

下面是一份初始化Gradle构建文件

build.gradle

 
   
   
 
  1. buildscript {

  2.    repositories {

  3.        mavenCentral()

  4.    }

  5.    dependencies {

  6.        classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.7.RELEASE")

  7.    }

  8. }

  9. apply plugin: 'java'

  10. apply plugin: 'eclipse'

  11. apply plugin: 'idea'

  12. apply plugin: 'org.springframework.boot'

  13. jar {

  14.    baseName = 'gs-spring-boot'

  15.    version =  '0.1.0'

  16. }

  17. repositories {

  18.    mavenCentral()

  19. }

  20. sourceCompatibility = 1.8

  21. targetCompatibility = 1.8

  22. dependencies {

  23.    // tag::jetty[]

  24.    compile("org.springframework.boot:spring-boot-starter-web") {

  25.        exclude module: "spring-boot-starter-tomcat"

  26.    }

  27.    compile("org.springframework.boot:spring-boot-starter-jetty")

  28.    // end::jetty[]

  29.    // tag::actuator[]

  30.    compile("org.springframework.boot:spring-boot-starter-actuator")

  31.    // end::actuator[]

  32.    testCompile("junit:junit")

  33. }

Spring Boot gradle 插件提供了非常多方便的功能:

  • 将 classpath 里面所有用到的 jar 包构建成一个可执行的 JAR 文件,使得运行和发布你的服务变得更加便捷

  • 搜索 publicstaticvoidmain()方法并且将它标记为可执行类

  • 提供了将内部依赖的版本都去匹配 Spring Boot 依赖的版本,你可以根据你的需要来重写版本,但是它默认提供给了 Spring Boot 依赖的版本

使用 Maven 构建项目

首先你需要编写基础构建脚本。在构建 Spring 应用的时候,你可以使用任何你喜欢的系统来构建,这里提供一份你可能需要用 Maven 构建的代码。如果你对 Maven 还不是很熟悉,你可以先去看下如何使用 Maven 构建 Java 项目.

创建 Maven 目录结构

在你的项目根目录,创建如下的子目录结构;例如,如果你使用的是 *nix系统,你可以使用 mkdir-p src/main/java/hello

 
   
   
 
  1. └── src

  2.    └── main

  3.        └── java

  4.            └── hello

pom.xml

 
   
   
 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  3.    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

  4.    <modelVersion>4.0.0</modelVersion>

  5.    <groupId>org.springframework</groupId>

  6.    <artifactId>gs-messaging-rabbitmq</artifactId>

  7.    <version>0.1.0</version>

  8.    <parent>

  9.        <groupId>org.springframework.boot</groupId>

  10.        <artifactId>spring-boot-starter-parent</artifactId>

  11.        <version>1.5.7.RELEASE</version>

  12.    </parent>

  13.    <properties>

  14.        <java.version>1.8</java.version>

  15.    </properties>

  16.    <dependencies>

  17.        <dependency>

  18.            <groupId>org.springframework.boot</groupId>

  19.            <artifactId>spring-boot-starter-amqp</artifactId>

  20.        </dependency>

  21.    </dependencies>

  22.    <build>

  23.        <plugins>

  24.            <plugin>

  25.                <groupId>org.springframework.boot</groupId>

  26.                <artifactId>spring-boot-maven-plugin</artifactId>

  27.            </plugin>

  28.        </plugins>

  29.    </build>

  30. </project>

Spring Boot Maven 插件 提供了非常多方便的功能:

  • 将 classpath 里面所有用到的 jar 包构建成一个可执行的 JAR 文件,使得运行和发布你的服务变得更加便捷

  • 搜索 publicstaticvoidmain()方法并且将它标记为可执行类

  • 提供了将内部依赖的版本都去匹配 Spring Boot 依赖的版本.你可以根据你的需要来重写版本,但是它默认提供给了 Spring Boot 依赖的版本。

使用你的 IDE 进行构建

  • 如何在Spring Tool Suite中构建.

  • 如何在IntelliJ IDEA中构建.

安装 RabbitMQ

在构建消息应用之前,需要先安装 RabbitMQ 消息中间件服务,中间件服务器会处理发送和接受消息。

RabbitMQ 是一个基于 AMQP协议的消息中间件。它完全开源,你可以在这里http://www.rabbitmq.com/download.html去下载它,如果你使用的是 Mac 电脑,你可以使用 homebrew 来安装:

 
   
   
 
  1. brew install rabbitmq

解压下载文件,并且使用默认配置启动服务.

 
   
   
 
  1. rabbitmq-server

启动后,你可以看到下面的提示:

 
   
   
 
  1.            RabbitMQ 3.1.3\. Copyright (C) 2007-2013 VMware, Inc.

  2. ##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/

  3. ##  ##

  4. ##########  Logs: /usr/local/var/log/rabbitmq/rabbit@localhost.log

  5. ######  ##        /usr/local/var/log/rabbitmq/rabbit@localhost-sasl.log

  6. ##########

  7.            Starting broker... completed with 6 plugins.

如果你本地安装了 Docker,你也可以通过 Docker Compose 的方式来快速启动一个 RabbitMQ 服务。下面是 Github 上面一个建立 RabbitMQ 服务的 docker-compse.yml,它非常简单:

docker-compose.yml

 
   
   
 
  1. rabbitmq:

  2.  image: rabbitmq:management

  3.  ports:

  4.    - "5672:5672"

  5.    - "15672:15672"

将这个文件放到你当前的目录,并且使用 docker-compose命令,就可以有一个运行 RabbitMQ 的容器了。

创建 RabbitMQ 消息接收者

对于一些使用消息的应用,你通常都需要创建一个消息接收者来响应已经发布的消息

src/main/java/hello/Receiver.java

 
   
   
 
  1. package hello;

  2. import java.util.concurrent.CountDownLatch;

  3. import org.springframework.stereotype.Component;

  4. @Component

  5. public class Receiver {

  6.    private CountDownLatch latch = new CountDownLatch(1);

  7.    public void receiveMessage(String message) {

  8.        System.out.println("Received <" + message + ">");

  9.        latch.countDown();

  10.    }

  11.    public CountDownLatch getLatch() {

  12.        return latch;

  13.    }

  14. }

这个接收者是一个非常简单的 POJO ,它定义了一个用来接收消息的方法。如果你自己实现,你也可以给相应的接收方法取任何你喜欢的名字。

为了方便,POJO里面定义了一个 CountDownLatch。它能够在接收到消息的时候给我们一些提示信号。在正式生产的环境里,你是不太可能像这样操作的。

注册监听器并且发送消息

Spring AMQP 的 RabbitTemplate 提供了任何你想要通过 RabbitMQ 发送和接受消息的任何功能。当然,你需要先做一些配置:

  • 一个消息监听容器

  • 声明队列,交换机,并且将它们两者绑定

  • 一个发送消息来测试监听器的组件类

Spring Boot 自动创建了一个连接工厂(译者注:RabbitMQ中的Connection Factory)和一个 RabbitTemplate 用来减少你需要写的大量代码。

你会使用 RabbitTemplate来发送消息,并且你会注册一个消息监听器的接收者来接收消息。连接工厂已经在底层做了一些实现,来允许他们连接到 RabbitMQ 服务器。

src/main/java/hello/Application.java

 
   
   
 
  1. package hello;

  2. import org.springframework.amqp.core.Binding;

  3. import org.springframework.amqp.core.BindingBuilder;

  4. import org.springframework.amqp.core.Queue;

  5. import org.springframework.amqp.core.TopicExchange;

  6. import org.springframework.amqp.rabbit.connection.ConnectionFactory;

  7. import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;

  8. import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;

  9. import org.springframework.boot.SpringApplication;

  10. import org.springframework.boot.autoconfigure.SpringBootApplication;

  11. import org.springframework.context.annotation.Bean;

  12. @SpringBootApplication

  13. public class Application {

  14.    final static String queueName = "spring-boot";

  15.    @Bean

  16.    Queue queue() {

  17.        return new Queue(queueName, false);

  18.    }

  19.    @Bean

  20.    TopicExchange exchange() {

  21.        return new TopicExchange("spring-boot-exchange");

  22.    }

  23.    @Bean

  24.    Binding binding(Queue queue, TopicExchange exchange) {

  25.        return BindingBuilder.bind(queue).to(exchange).with(queueName);

  26.    }

  27.    @Bean

  28.    SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,

  29.            MessageListenerAdapter listenerAdapter) {

  30.        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();

  31.        container.setConnectionFactory(connectionFactory);

  32.        container.setQueueNames(queueName);

  33.        container.setMessageListener(listenerAdapter);

  34.        return container;

  35.    }

  36.    @Bean

  37.    MessageListenerAdapter listenerAdapter(Receiver receiver) {

  38.        return new MessageListenerAdapter(receiver, "receiveMessage");

  39.    }

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

  41.        SpringApplication.run(Application.class, args);

  42.    }

  43. }

@SpringBootApplication 是一个非常方便的注解,它增加了以下注解的所有功能

  • @Configuration 标记这个类是应用上下文 Bean 的源定义

  • @EnableAutoConfiguration 告诉 SpringBoot 启动的时候在 classpath 设置、其它已经装载的 Bean 以及其它配置文件的基础上自动进行配置 Bean

  • 通常你会在SpringMVC应用上使用 @EnableMvc,但是Spring Boot 在看到spring-webmvc 在它的classpath目录下的时候,它会自动加载该注解。这个注解标记了这个应用是一个web应用,并且会激活一些关键功能,比如说加载 DispatcherServlet

  • @ComponetScan 告诉 Spring 在 hello 包下扫描其它的注解,如组件(componets),配置(configurations),或者服务(services),Spring 也会通过它找到控制器(controllers)

main() 方法里面通过调用 Spring Boot 的 SpringApplication.run()方法来启动应用。你有没有注意到到现在还没有写过一行 XML ?甚至也没有 web.xml文件。这个 web 应用完全 100% 都是使用的 Java,并且你还不需要对任何应用的基础设置进行配置。

通过 listenerAdapter()来定义的 Bean,用来在 container()方法里面注册称为一个消息监听器。它会监听来自"spring-boot"队列的消息。因为接受者类是一个 POJO,它需要在 MessageListenAdapter里面进行一层包装,然后在这里我们再调用它的 receiveMessage方法。

基于 JMS 的队列和 基于 AMQP 的队列有些不同。比如,JMS 只发送消息给一个消费者,而 AMQP 也可以做到同样的事,并且 AMQP 的生产者不是直接发送消息给队列,它将消息发送一个交换机,交换机可以将消息发送给一个队列,也可以发送给多个队列,就像 JMS 的 topics。了解更多AMQP

消息监听容器和接收消息的 Bean ,你都应该监听。如果要发送消息,你需要使用 RabbitTemplate

queue()方法创建了一个AMQP队列。 exchange()方法创建了一个 topic交换机。当 RabbitTemplate 发布消息到一个交换机的时候, binding()方法将队列和交换机两者进行了绑定。

Spring AMQP 要求 Queue, TopicExchange, Binding被声明成了 Spring 的高级 Beans,之后才能正确的执行。

发送文本消息

文本消息通过一个 CommandLineRunner类来发送,它会等待接收方锁并且关闭应用的上下文:

src/main/java/hello/Runner.java

 
   
   
 
  1. package hello;

  2. import java.util.concurrent.TimeUnit;

  3. import org.springframework.amqp.rabbit.core.RabbitTemplate;

  4. import org.springframework.boot.CommandLineRunner;

  5. import org.springframework.context.ConfigurableApplicationContext;

  6. import org.springframework.stereotype.Component;

  7. @Component

  8. public class Runner implements CommandLineRunner {

  9.    private final RabbitTemplate rabbitTemplate;

  10.    private final Receiver receiver;

  11.    private final ConfigurableApplicationContext context;

  12.    public Runner(Receiver receiver, RabbitTemplate rabbitTemplate,

  13.            ConfigurableApplicationContext context) {

  14.        this.receiver = receiver;

  15.        this.rabbitTemplate = rabbitTemplate;

  16.        this.context = context;

  17.    }

  18.    @Override

  19.    public void run(String... args) throws Exception {

  20.        System.out.println("Sending message...");

  21.        rabbitTemplate.convertAndSend(Application.queueName, "Hello from RabbitMQ!");

  22.        receiver.getLatch().await(10000, TimeUnit.MILLISECONDS);

  23.        context.close();

  24.    }

  25. }

在测试中runner会被mock掉,目的是为了接受者能够在隔离的环境下测试。

运行应用

main()方法通过创建一个 Spring 应用上下文来启动了程序。它会启动消息监听者容器,容器启动后会监听消息。这里自动执行了一个 Runner类:它会从应用上下文中检查 RabbitTemplate,之后会在"spring-boot"队列上发送"Hello from RabbitMQ"消息。最后它会关闭 Spring 应用上下文,然后程序就停止了。

构建一个可执行的JAR

你可以通过使用 Gradle 或者 Maven 命令行来运行一个应用。或者你可以先构建一个包含了所有依赖、类、和配置的可执行 JAR 文件,然后运行它。这使得在整个开发生命周期中,以及在不同的环境中,都很容易将应用程序进行部署、版本控制和服务发布。

如果你使用 Gradle ,你可以使用 ./gradlew来启动应用,或者你可以使用 ./gradlew build来构建一个 JAR 文件。之后,你可以通过运行 JAR 文件:

 
   
   
 
  1. java -jar build/libs/gs-messaging-rabbitmq-0.1.0.jar

如果你使用 Maven ,你可以使用 ./mvnw spring-boot:run来运行应用。或者你可以使用 ./mvnw cleanpackage来构建一个 JAR 包。之后你可以运行JAR文件:

 
   
   
 
  1. java -jar target/gs-messaging-rabbitmq-0.1.0.jar

上面的过程是创建一个可以运行的JAR,如果你需要构建成一个WAR:[怎样构建WAR文件][2]

你应该可以看到下面的输出:

 
   
   
 
  1. Sending message...

  2. Received

总结

恭喜!你已经使用 Spring 和 RabbitMQ 开发了一个简单的 发布-订阅应用。你也可以使用 Spring 和 RabbitMQ 来做更多的操作,上面的例子只是一个好的开始。

了解更多

下面的指南也非常有帮助:

  • Messaging with Redis

  • Messaging with JMS

  • 使用Spring Boot构建应用

本文由spring4all.com翻译小分队创作,采用知识共享-署名-非商业性使用-相同方式共享 4.0 国际 许可 协议进行许可。


加入


https://github.com/SpringForAll/spring-guides-translation


推荐:《》

上一篇:《》




最好的赞赏

就是你的关注


以上是关于译Spring官方教程:Spring Boot整合消息中间件RabbitMQ的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot2 系列教程Spring Boot 整合 Freemarker

SpringBoot自学教程 | 第四篇:Spring Boot整合mybatis

Spring Boot教程(十三)整合elk

Spring Boot2 系列教程 | 整合 thymeleaf

Spring boot整合jsp

Spring Boot教程整合elk