SpringBoot集成RabbitMQ

以前用過ActiveMQ,最近了解下RabbitMQ的用法和原理,

下面直接開始,在瞭解代碼部分集成之前,讀者先自行了解下RabbitMQ的一些基本知識,以及RabbitMQ的安裝,這裏不再重複,推薦下這篇博客還是不錯的https://www.cnblogs.com/grasp/p/9448660.html

首先介紹幾個基本概念:

enter image description here

1、生產者:發送消息的程序
2、消費者:監聽接收消費消息的程序
3、消息:一串二進制數據流
4、隊列:消息的暫存區/存儲區
5、交換機:消息的中轉站,用於接收分發消息。其中有 fanout、direct、topic、headers 四種
6、路由:相當於密鑰/第三者,與交換機綁定即可路由消息到指定的隊列!

代碼部分

1.jar包的引入

<!--集成rabbitMQ-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
			<version>1.5.2.RELEASE</version>
		</dependency>

2、配置配置文件addlication.yml文件

#----------------------------------RabbitMQ----------------------------------
    rabbitmq:
        host: localhost
        port: 5672
        username: guest
        password: guest

3、配置RabbitConfig配置類:

我們需要以 Configuration 的方式配置 RabbitMQ 並以 Bean 的方式顯示注入 RabbitMQ 在發送接收處理消息時相關 Bean 組件配置

package com.dcx.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
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;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class RabbitConfig {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Value("${spring.rabbitmq.host}")
    private String host;

    @Value("${spring.rabbitmq.port}")
    private int port;

    @Value("${spring.rabbitmq.username}")
    private String username;

    @Value("${spring.rabbitmq.password}")
    private String password;

    public static final String EXCHANGE_A = "my-mq-exchange_A";

    public static final String QUEUE_A = "QUEUE_A";

    public static final String ROUTINGKEY_A = "spring-boot-routingKey_A";


    @Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host,port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setPublisherConfirms(true);
        return connectionFactory;
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    //必須是prototype類型
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());
        return template;
    }

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


    /**
     * 針對消費者配置
     * 1. 設置交換機類型
     * 2. 將隊列綁定到交換機
     FanoutExchange: 將消息分發到所有的綁定隊列,無routingkey的概念
     HeadersExchange :通過添加屬性key-value匹配
     DirectExchange:按照routingkey分發到指定隊列
     TopicExchange:多關鍵字匹配
     */
    @Bean
    public DirectExchange defaultExchange() {
        return new DirectExchange(EXCHANGE_A);//交換器名稱、是否持久化、是否自動刪除
    }
    /**
     * 獲取隊列A
     * @return
     */
    @Bean
    public Queue queueA() {
        return new Queue(QUEUE_A, true);  //隊列名字,是否持久化
    }
    @Bean
    public Binding binding() {

        return BindingBuilder.bind(queueA()).to(defaultExchange()).with(RabbitConfig.ROUTINGKEY_A);
    }
}

消息生產者MsgProducer

package com.dcx.common.rabbitmq;

import com.dcx.config.RabbitConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.UUID;

@Component
public class MsgProducer implements RabbitTemplate.ConfirmCallback {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    //由於rabbitTemplate的scope屬性設置爲ConfigurableBeanFactory.SCOPE_PROTOTYPE,所以不能自動注入
    private RabbitTemplate rabbitTemplate;
    /**
     * 構造方法注入rabbitTemplate
     */
    @Autowired
    public MsgProducer(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
        rabbitTemplate.setConfirmCallback(this); //rabbitTemplate如果爲單例的話,那回調就是最後設置的內容
    }

    public void sendMsg(String content) {
        CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
        //把消息放入ROUTINGKEY_A對應的隊列當中去,對應的是隊列A
        rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_A, RabbitConfig.ROUTINGKEY_A, content, correlationId);
    }
    /**
     * 回調
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        logger.info(" 回調id:" + correlationData);
        if (ack) {
            logger.info("消息成功消費");
        } else {
            logger.info("消息消費失敗:" + cause);
        }
    }
}

消息消費者

package com.dcx.common.rabbitmq;

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

@Component
@RabbitListener(queues = "QUEUE_A")
public class Receiver {

    @RabbitHandler
    public void process(String hello) {
        System.out.println("Receiver  : " + hello);
    }

}

控制層接口測試

package com.dcx.modules.sys.controller;

import com.dcx.common.rabbitmq.MsgProducer;
import com.dcx.common.rabbitmq.Sender;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("rabbitmq")
@Api("RabbitMQ接口測試")
public class RabbitMQController {

    @Autowired
    private MsgProducer msgProducer;

    @PostMapping(value = "/sendmsg")
    @ApiOperation(value = "發送固定消息")
    public String helloTest(){
        msgProducer.sendMsg("1111111111111111111111");
        return "success";
    }
}

項目運行後,進行調用接口

最終控制檯打印結果

 

-------------------------------------------------------------------------分隔符---------------------------------------------------------------------------------

上面只是實現簡單的消息發送,接收功能

 

 

 

 

 

發佈了87 篇原創文章 · 獲贊 115 · 訪問量 28萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章