RabbitMQ 与 SpringBoot 整合

433 阅读2分钟

Spring 集成了 RabbitMQ,只需要使用 Spring-Rabbit 去操作 RabbitMQ。Github网址

SpringBoot 中使用 RabbitMQ 更加简单,只需要在 pom 中加入 amqp 启动器,application.yml 中配置 RabbitMQ 地址信息,发送消息使用 RabbitTemplate,接收消息使用 @RabbitListener 即可。

生产者

注意:生产者只关注发往哪个交换机或者队列,不关注交换机与队列之间的绑定关系(这事儿是消费者需要关心的)。

pom 文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>producer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

启动类

package com.example.producer;

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

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

发送消息的控制器

package com.example.producer.controller;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ProducerController {

  @Autowired
  private RabbitTemplate rabbitTemplate;

  @GetMapping("/sendMessage")
  public String sendMessage(String exchange, String routingKey, String message, Integer times) {
    if (times == null) {
      times = 1;
    }
    int realTimes = 0;
    for (int i = 0; i < times; i++) {
      rabbitTemplate.convertAndSend(exchange, routingKey, message + i);
      realTimes++;
    }
    return "总共发送 " + realTimes + " 条消息。";
  }
}

application.yml 配置文件

server:
  port: 8081
spring:
  rabbitmq:
    host: 192.168.2.100
    port: 5672
    username: dev
    password: 123456
    virtual-host: /dev

测试,在浏览器发起请求

http://127.0.0.1:8081/sendMessage?exchange=testTopic&routingKey=test.halo&message=HelloWorld!&times=100
  • 如果生产者发送消息的交换机不存在,方法不会报错,但是 RabbitMQ 并不会自动生成交换机,消息丢失。

  • 所以先启动消费者,或者在生产者工程里面加交换机的声明。

消费者

创建交换机、队列、绑定关系时,有两种方法,一种是建造者模式,一种是正常新建对象。将绑定关系放在消费者,表明消费者想要消费哪些消息。

pom 文件

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>consumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <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>

启动类

package com.example.consumer;

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

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

交换机、队列、绑定关系配置类

package com.example.consumer.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitConfig {
  @Bean
  public Exchange topicExchange() {
//    return new TopicExchange("testTopic", true, false);
    return ExchangeBuilder.topicExchange("testTopic").durable(true).build();
  }

  @Bean
  public Queue topicQueue() {
//    return new Queue("testQueue", true, false, false);
    return QueueBuilder.durable("testQueue").build();
  }

  @Bean
  public Binding topicBinding(Exchange topicExchange, Queue topicQueue) {
//    return new Binding("testQueue", Binding.DestinationType.QUEUE, "testTopic", "test.#", null);
    return BindingBuilder.bind(topicQueue).to(topicExchange).with("test.#").noargs();
  }
}

监听器,接收消息

package com.example.consumer.listener;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class TestListener {

  @RabbitListener(queues = "testQueue")
  public void consume(String message) {
    System.out.printf("Message is %s.\n", message);
  }
}

application.yml 配置文件

spring:
  rabbitmq:
    host: 192.168.2.100
    port: 5672
    username: dev
    password: 123456
    virtual-host: /dev
  • consume 方法中的传参类型以生产者发送的消息类型来确定,比如生产者发送字符数组 byte[],那么消费者接受就使用 byte[]。

So easy~~~