快速導覽(給心急的人)

簡介

這是 Spring AMQP 的五分鐘快速導覽,協助您快速入門。

先決條件:安裝並執行 RabbitMQ Broker (https://www.rabbitmq.com/download.html)。然後取得 spring-rabbit JAR 及其所有相依性 - 最簡單的方法是在您的建置工具中宣告相依性。例如,對於 Maven,您可以執行類似以下的操作

<dependency>
  <groupId>org.springframework.amqp</groupId>
  <artifactId>spring-rabbit</artifactId>
  <version>3.1.6</version>
</dependency>

對於 Gradle,您可以執行類似以下的操作

compile 'org.springframework.amqp:spring-rabbit:3.1.6'

相容性

最低 Spring Framework 版本相依性為 6.1.0。

最低 amqp-client Java 用戶端程式庫版本為 5.18.0。

用於串流佇列的最低 stream-client Java 用戶端程式庫版本為 0.12.0。

非常非常快速

本節提供最快速的入門介紹。

首先,新增以下 import 陳述式,使本節後續的範例能夠運作

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 來發送和接收訊息

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 抽象化。它會快取通道(以及可選的連線)以供重複使用。我們依賴 Broker 中的預設交換器(因為發送中未指定任何交換器),以及所有佇列依其名稱與預設交換器的預設繫結(因此,我們可以使用佇列名稱作為發送中的路由金鑰)。這些行為在 AMQP 規範中定義。

使用 XML 設定

以下範例與前一個範例相同,但將資源設定外部化到 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,並代表使用者將它們宣告給 Broker。因此,您無需在簡單的 Java 驅動程式中明確使用該 Bean。XML 綱要中有很多選項可用於設定元件的屬性。您可以使用 XML 編輯器的自動完成功能來探索它們並查看其文件。

使用 Java 設定

以下範例重複了與前一個範例相同的範例,但使用 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");
    }
}

使用 Spring Boot 自動設定和非同步 POJO 監聽器

Spring Boot 會自動設定基礎架構 Bean,如下列範例所示

@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);
    }

}