Spring Boot 2.1.0.RELEASE 整合 RabbitMQ

pom.xml:

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

    <groupId>com.wuychn</groupId>
    <artifactId>springboot-rabbitmq</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>springboot-rabbitmq</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- rabbitmq依赖 -->
        <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>

application.yml:

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    # 消息发送到交换器确认机制,是否确认回调
    publisher-confirms: true
    publisher-returns: true
server:
  port: 8080

交换器配置类ExchangeConfig:

package com.wuychn.springbootrabbitmq.config;

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

@Configuration
public class ExchangeConfig {

    public static final String EXCHANGE_NAME = "exchange";

    @Bean
    public DirectExchange directExchange() {
        // 参数依次是交换器名称、是否持久化、是否自动删除
        return new DirectExchange(EXCHANGE_NAME, true, false);
    }

}

队列配置类QueueConfig:

package com.wuychn.springbootrabbitmq.config;

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

@Configuration
public class QueueConfig {

    // 队列1的名称
    public static final String QUEUE_NAME_1 = "queue1";

    // 队列2的名称
    public static final String QUEUE_NAME_2 = "queue2";

    @Bean
    public Queue queue1() {
        // 参数依次为:队列名称,是否持久化,是否排他,是否自动删除
        return new Queue(QUEUE_NAME_1, true, false, false);
    }

    @Bean
    public Queue queue2() {
        // 参数依次为:队列名称,是否持久化,是否排他,是否自动删除
        return new Queue(QUEUE_NAME_2, true, false, false);
    }

}

RabbitMQ配置类RabbitMqConfig:

package com.wuychn.springbootrabbitmq.config;

import com.wuychn.springbootrabbitmq.callback.MsgSendConfirmCallBack;
import com.wuychn.springbootrabbitmq.callback.MsgSendReturnCallback;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class RabbitMqConfig {

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

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

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

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

    // 路由键1
    public static final String ROUTING_KEY_1 = "routingKey1";

    // 路由键2
    public static final String ROUTING_KEY_2 = "routingKey2";

    @Autowired
    public QueueConfig queueConfig;

    @Autowired
    public ExchangeConfig exchangeConfig;

//    @Autowired
//    private ConnectionFactory connectionFactory;

    /**
     * ConnectionFactory,可以直接注入,如上
     *
     * @return
     */
    //@Bean
    public ConnectionFactory connectionFactory() {
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host, port);
        connectionFactory.setUsername(username);
        connectionFactory.setPassword(password);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setPublisherConfirms(true);
        return connectionFactory;
    }

    /**
     * 将消息队列1和交换器绑定
     *
     * @return
     */
    @Bean
    public Binding binding1() {
        return BindingBuilder.bind(queueConfig.queue1()).to(exchangeConfig.directExchange()).with(RabbitMqConfig.ROUTING_KEY_1);
    }

    /**
     * 将消息队列2和交换器绑定
     *
     * @return
     */
    @Bean
    public Binding binding2() {
        return BindingBuilder.bind(queueConfig.queue2()).to(exchangeConfig.directExchange()).with(RabbitMqConfig.ROUTING_KEY_2);
    }


    /**
     * 自定义rabbitTemplate用于数据的接收和发送
     * 可以设置消息确认机制和回调
     *
     * @return
     */
    @Bean
    public RabbitTemplate rabbitTemplate() {
        RabbitTemplate template = new RabbitTemplate(connectionFactory());

        // 可以自定义消息转换器,默认使用的JDK的,所以消息对象需要实现Serializable
        // template.setMessageConverter();

        // 若使用 confirm-callback 或 return-callback,
        // 必须要配置 publisherConfirms 或 publisherReturns为true
        // 每个 rabbitTemplate 只能有一个confirm-callback和return-callback
        template.setConfirmCallback(msgSendConfirmCallBack());

        // 使用 return-callback 时必须设置 mandatory 为true
        // 或者在配置中设置 mandatory-expression 的值为true
        // 可针对每次请求的消息去确定 mandatory 的 boolean 值
        // 只能在提供 return-callback 时使用,与 mandatory 互斥
        // 关于 msgSendConfirmCallBack 和 msgSendReturnCallback 的回调说明:
        //      1、如果消息没有到 exchange,则 confirm 回调, ack=false
        //      2、如果消息到达 exchange, 则 confirm 回调, ack=true
        //      3、exchange到queue成功, 则不回调return
        //      4、exchange到queue失败, 则回调return(需设置mandatory=true, 否则不会回调, 消息就丢了)
        template.setReturnCallback(msgSendReturnCallback());
        template.setMandatory(true);
        return template;
    }

    /**
     * 消息确认机制
     *
     * @return
     */
    @Bean
    public MsgSendConfirmCallBack msgSendConfirmCallBack() {
        return new MsgSendConfirmCallBack();
    }

    @Bean
    public MsgSendReturnCallback msgSendReturnCallback() {
        return new MsgSendReturnCallback();
    }

}

MsgSendConfirmCallBack:

package com.wuychn.springbootrabbitmq.callback;


import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;

public class MsgSendConfirmCallBack implements RabbitTemplate.ConfirmCallback {

    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
        System.out.println("消息发送回调:" + correlationData);
        if (ack) {
            System.out.println("消息发送成功");
        } else {
            System.out.println("消息发送失败:" + cause + "\n重新发送");
        }
    }
}

MsgSendReturnCallback:

package com.wuychn.springbootrabbitmq.callback;

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

public class MsgSendReturnCallback implements RabbitTemplate.ReturnCallback {
    
    // 消息如到达了队列不会回调,只有没有到达队列才会回调这个方法,所以不像 confirm 的回调需要判断是否成功
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        System.out.println("回馈消息:" + message);
    }
}

Producer1:

package com.wuychn.springbootrabbitmq.producer;

import com.wuychn.springbootrabbitmq.config.ExchangeConfig;
import com.wuychn.springbootrabbitmq.config.RabbitMqConfig;
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;

@Component
public class Producer1 {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 发送消息
     *
     * @param uuid
     * @param message 消息
     */
    public void send(String uuid, Object message) {
        CorrelationData correlationId = new CorrelationData(uuid);
        rabbitTemplate.convertAndSend(ExchangeConfig.EXCHANGE_NAME, RabbitMqConfig.ROUTING_KEY_1,
                message, correlationId);
    }

}

Producer2:

package com.wuychn.springbootrabbitmq.producer;

import com.wuychn.springbootrabbitmq.config.ExchangeConfig;
import com.wuychn.springbootrabbitmq.config.RabbitMqConfig;
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;

@Component
public class Producer2 {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 发送消息
     *
     * @param uuid
     * @param message 消息
     */
    public void send(String uuid, Object message) {
        CorrelationData correlationId = new CorrelationData(uuid);
        rabbitTemplate.convertAndSend(ExchangeConfig.EXCHANGE_NAME, RabbitMqConfig.ROUTING_KEY_2,
                message, correlationId);
    }

}

Consumer1:

package com.wuychn.springbootrabbitmq.consumer;

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

@Component
public class Consumer1 {

    /**
     * 指定从哪个队列订阅消息,可以指定多个,用逗号隔开
     *
     * @param message
     */
    @RabbitListener(queues = {"queue1"})
    public void handleMessage(String message) {
        // 处理消息
        System.out.println("consumer1收到消息:" + message);
    }

}

Consumer2:

package com.wuychn.springbootrabbitmq.consumer;

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

/**
 * 指定从哪个队列订阅消息,可以指定多个,用逗号隔开
 * 注意,和Consumer1不同,这里的@RabbitListener是写在类上的
 * 在具体的处理方法上需要再加一个@RabbitHandler注解
 */
@Component
@RabbitListener(queues = {"queue2"})
public class Consumer2 {

    /**
     * 处理接收到的消息
     *
     * @param message
     */
    @RabbitHandler
    public void handleMessage(String message) {
        // 处理消息
        System.out.println("consumer2收到消息:" + message);
    }

}

MsgController:

package com.wuychn.springbootrabbitmq.controller;

import com.wuychn.springbootrabbitmq.producer.Producer1;
import com.wuychn.springbootrabbitmq.producer.Producer2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

@RestController
public class MsgController {

    @Autowired
    private Producer1 producer1;

    @Autowired
    private Producer2 producer2;


    @GetMapping("/send1")
    public String send1(String msg) {
        String uuid = UUID.randomUUID().toString();
        producer1.send(uuid, msg);
        return uuid;
    }

    @GetMapping("/send2")
    public String send2(String msg) {
        String uuid = UUID.randomUUID().toString();
        producer2.send(uuid, msg);
        return uuid;
    }
}

项目结构:

 

参考:

Springboot整合一之Springboot整合RabbitMQ

Spring Boot整合RabbitMQ详细教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值