Quick Tour for the impatient

Introduction

这是 Spring AMQP 入门的五分钟游览。

This is the five-minute tour to get started with Spring AMQP.

先决条件:安装并运行 RabbitMQ 代理 ( https://www.rabbitmq.com/download.html)。然后获取 spring-rabbit JAR 及其所有依赖项 - 最简单的办法是在构建工具中声明一个依赖项。例如,对于 Maven,可以执行类似以下的操作:

Prerequisites: Install and run the RabbitMQ broker (https://www.rabbitmq.com/download.html). Then grab the spring-rabbit JAR and all its dependencies - the easiest way to do so is to declare a dependency in your build tool. For example, for Maven, you can do something resembling the following:

<dependency>
  <groupId>org.springframework.amqp</groupId>
  <artifactId>spring-rabbit</artifactId>
  <version>{project-version}</version>
</dependency>

对于 Gradle,您可以执行类似以下操作:

For Gradle, you can do something resembling the following:

compile 'org.springframework.amqp:spring-rabbit:{project-version}'

Compatibility

最低 Spring Framework 版本依赖项为 6.1.0。

The minimum Spring Framework version dependency is 6.1.0.

最低 amqp-client Java 客户端库版本为 5.18.0。

The minimum amqp-client Java client library version is 5.18.0.

最低流式队列的 stream-client Java 客户端库版本为 0.12.0。

The minimum stream-client Java client library for stream queues is 0.12.0.

Very, Very Quick

本节提供了最快的介绍。

This section offers the fastest introduction.

首先,添加以下 import 语句,以便本节后面的示例可以运行:

First, add the following import statements to make the examples later in this section work:

import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

以下示例使用常规的 Java 必须式语言来发送和接收消息:

The following example uses plain, imperative Java to send and receive a message:

ConnectionFactory connectionFactory = new CachingConnectionFactory();
AmqpAdmin admin = new RabbitAdmin(connectionFactory);
admin.declareQueue(new Queue("myqueue"));
AmqpTemplate template = new RabbitTemplate(connectionFactory);
template.convertAndSend("myqueue", "foo");
String foo = (String) template.receiveAndConvert("myqueue");

请注意,原生 Java Rabbit 客户端中还有一个 ConnectionFactory。我们在前述代码中使用了 Spring 抽象。它会缓存通道(以及选择性地缓存连接)以供重复使用。我们使用代理中的默认交换(因为发送过程中未指定任何交换)以及所有队列到默认交换的默认绑定(由此一来,我们可以在发送过程中将队列名称用作路由密钥)。这些行为在 AMQP 规范中定义。

Note that there is also a ConnectionFactory in the native Java Rabbit client. We use the Spring abstraction in the preceding code. It caches channels (and optionally connections) for reuse. We rely on the default exchange in the broker (since none is specified in the send), and the default binding of all queues to the default exchange by their name (thus, we can use the queue name as a routing key in the send). Those behaviors are defined in the AMQP specification.

With XML Configuration

以下示例与前述示例相同,但将资源配置外部化到 XML:

The following example is the same as the preceding example but externalizes the resource configuration to XML:

ApplicationContext context =
    new GenericXmlApplicationContext("classpath:/rabbit-context.xml");
AmqpTemplate template = context.getBean(AmqpTemplate.class);
template.convertAndSend("myqueue", "foo");
String foo = (String) template.receiveAndConvert("myqueue");
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:rabbit="http://www.springframework.org/schema/rabbit"
       xsi:schemaLocation="http://www.springframework.org/schema/rabbit
           https://www.springframework.org/schema/rabbit/spring-rabbit.xsd
           http://www.springframework.org/schema/beans
           https://www.springframework.org/schema/beans/spring-beans.xsd">

    <rabbit:connection-factory id="connectionFactory"/>

    <rabbit:template id="amqpTemplate" connection-factory="connectionFactory"/>

    <rabbit:admin connection-factory="connectionFactory"/>

    <rabbit:queue name="myqueue"/>

</beans>

默认情况下,“<rabbit:admin/>”声明会自动查找 QueueExchangeBinding 类型的 bean,并代表用户向代理声明这些 bean。因此,不必在简单的 Java 驱动程序中明确使用该 bean。有大量选项可用于配置 XML 模式中组件的属性。您可以使用 XML 编辑器的自动完成功能来探索它们并查看其文档。

By default, the <rabbit:admin/> declaration automatically looks for beans of type Queue, Exchange, and Binding and declares them to the broker on behalf of the user. As a result, you need not use that bean explicitly in the simple Java driver. There are plenty of options to configure the properties of the components in the XML schema. You can use auto-complete features of your XML editor to explore them and look at their documentation.

With Java Configuration

以下示例重复了前述示例,但外部配置定义在 Java 中:

The following example repeats the same example as the preceding example but with the external configuration defined in Java:

ApplicationContext context =
    new AnnotationConfigApplicationContext(RabbitConfiguration.class);
AmqpTemplate template = context.getBean(AmqpTemplate.class);
template.convertAndSend("myqueue", "foo");
String foo = (String) template.receiveAndConvert("myqueue");

........

@Configuration
public class RabbitConfiguration {

    @Bean
    public CachingConnectionFactory connectionFactory() {
        return new CachingConnectionFactory("localhost");
    }

    @Bean
    public RabbitAdmin amqpAdmin() {
        return new RabbitAdmin(connectionFactory());
    }

    @Bean
    public RabbitTemplate rabbitTemplate() {
        return new RabbitTemplate(connectionFactory());
    }

    @Bean
    public Queue myQueue() {
       return new Queue("myqueue");
    }
}

With Spring Boot Auto Configuration and an Async POJO Listener

Spring Boot 会自动配置基础结构 bean,如下面的示例所示:

Spring Boot automatically configures the infrastructure beans, as the following example shows:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public ApplicationRunner runner(AmqpTemplate template) {
        return args -> template.convertAndSend("myqueue", "foo");
    }

    @Bean
    public Queue myQueue() {
        return new Queue("myqueue");
    }

    @RabbitListener(queues = "myqueue")
    public void listen(String in) {
        System.out.println(in);
    }

}