使用IDEA开发RabbitMQ教程系列(九)Spring Boot2.1.3集成最新版本Spring AMQP(RabbitMQ)

1、前言

前面得八篇文章相信小伙伴对RabbitMQ基础API有了一定得了解,今天我们来讲解如何使用Spring Boot来进行RabbitMQ得开发,不过如果小伙伴对RabbitMQ基础API还不了解得建议大家翻阅博主的前面8篇文章;我们就先从Spring AMQP开始介绍;

2、Spring AMQP

Spring AMQP项目将核心Spring概念应用基于AMQP的消息传递解决方案的开发。 Spring提供“模板”作为发送和接收消息的高级抽象。 Spring还为消息驱动的POJO提供支持。 这些库有助于管理AMQP资源,同时促进依赖注入和声明性配置的使用;简单说就是Spring AMQP帮我们对RabbitMQ进行了进一步得封装,并交给Spring管理和以前的Spring bean 一样让我们使用起来更加得方便;
让我们先来看一下一下官方文档中使用简单的命令式Java来发送和接收消息的代码:(注意我的注释)

//创建连接工厂
ConnectionFactory connectionFactory = new CachingConnectionFactory();
//AmqpAdmin是作用于操作RabbitMQ的类,可以创建队列 、 交换机 等等
AmqpAdmin admin = new RabbitAdmin(connectionFactory);
//创建队列
admin.declareQueue(new Queue("myqueue"));
//AmqpTemplate消息发送模板
AmqpTemplate template = new RabbitTemplate(connectionFactory);
//convertAndSend发送消息
template.convertAndSend("myqueue", "foo");
//receiveAndConvert 接收消息
String foo = (String) template.receiveAndConvert("myqueue");

通过以代码我们会发现,和我们基础RabbitMQ的构建方式还是很像的,同样拥有ConnectionFactory ,需要构建队列构建交换机(代码中没构建,使用的是RabbitMQ默认交换机),通过AmqpTemplate 发送、接收消息;那么交给Spring管理后我们需要如何来进行配置?从而实现上述代码的效果?

XML配置
<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
http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
http://www.springframework.org/schema/beans
http://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>

收发代码:

ApplicationContext context = new GenericXmlApplicationContext("classpath:/rabbit-context.xml");
AmqpTemplate template = context.getBean(AmqpTemplate.class);
template.convertAndSend("myqueue", "foo");
String foo = (String) template.receiveAndConvert("myqueue")
JAVA注解配置
//注解配置
@Configuration
public class RabbitConfiguration {
    @Bean
    public ConnectionFactory connectionFactory() {
        return new CachingConnectionFactory("localhost");
    }
    @Bean
    public AmqpAdmin amqpAdmin() {
        return new RabbitAdmin(connectionFactory());
    }
    @Bean
    public RabbitTemplate rabbitTemplate() {
        return new RabbitTemplate(connectionFactory());
    }
    @Bean
    public Queue myQueue() {
       return new Queue("myqueue");
    }
}

收发代码:

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

3、Spring AMQP的基本组件

与我们之前学习RabbitMQ一样,在使用Spring AMQP之前,我们有必要先去了解一下各个组件的一些介绍,便于我们快速理解与使用;更多详细的讲解请可以参考官方最新文档: Spring AMQP官方文档 这里就不过多介绍了,主要还是以实例来让大家来了解

4、基于Spring Boot集成Spring AMQP2.1.4

首先我们使用IDEA构建一个SpringBoot项目,SpringBoot版本选择2.1.3
在POM.XML文件中引入

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

在springboot配置文件 application.yml 中加入

spring:
  rabbitmq:
    addresses: 192.168.1.28:5672
    username: toher
    password: toher888
    connection-timeout: 15000
    virtual-host: /
    publisher-confirms: true #开启消息确认
    publisher-returns: true #开去消息Return
    template:
      mandatory: true #交换机找不到QUEUE时,会调用Basic.Return 命令将消息返回给生产者
    listener:
      direct:
        acknowledge-mode: manual # 开启手动 ,否则confirm自动确认
server:
  port: 8089

构建消息发布者,消息确认机制

@Component
public class RabbitSender implements RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;


    public void sendMsg() throws Exception {
        CorrelationData cd = new CorrelationData("123456789");
        rabbitTemplate.setReturnCallback(this);
        rabbitTemplate.convertAndSend("topicExchange001", "topicKey.send","测试发送",cd);
        //官方最新文档
        //从版本2.1开始,该CorrelationData对象具有ListenableFuture您可以用来获取结果的对象,
        //而不是ConfirmCallback在模板上使用
        boolean isAck = cd.getFuture().get(10, TimeUnit.SECONDS).isAck();
        //如果ACK true 进行业务处理
        if(isAck){
            //获取发送消息时候的 CorrelationData
            System.err.println("ID:" + cd.getId());
        }else{

        }
    }

    final RabbitTemplate.ReturnCallback returnCallback = new RabbitTemplate.ReturnCallback() {
        @Override
        public void returnedMessage(Message message, int replyCode, String replyText,
                                    String exchange, String routingKey) {
            System.err.println("--------------进入Return-------------");
            System.err.println("return exchange: " + exchange + ", routingKey: "
                    + routingKey + ", replyCode: " + replyCode + ", replyText: " + replyText);
        }
    };

    @Override
    public void returnedMessage(Message message, int replyCode, String replyText,
                                String exchange, String routingKey) {
        System.err.println("--------------进入Return-------------");
        System.err.println("return exchange: " + exchange + ", routingKey: "
                + routingKey + ", replyCode: " + replyCode + ", replyText: " + replyText);
    }

//也可以实现 RabbitTemplate.ConfirmCallback 即可
//    @Override
//    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
//        System.err.println("--------------进入Confirm-------------");
//        System.err.println("correlationData: " + correlationData);
//        System.err.println("ack: " + ack);
//        if(!ack){
//            System.err.println("异常处理....");
//        }
//    }
}

构建消息消费者

@Component
public class RabbitReceiver {

    /**@Exchange 默认durable=true 故不需要设置 **
     *
     * @param message
     * @param channel
     * @throws Exception
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "topicQueue001",
                    durable="true"),
            exchange = @Exchange(value = "topicExchange001"
                    type= "topic",
                    ignoreDeclarationExceptions = "true"),
            key = "topicKey.*")
    )
    @RabbitHandler
    public void onMessage(Message message, Channel channel) throws Exception {
        System.err.println("消费端Payload: " + message.getPayload());
        Long deliveryTag = (Long)message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
        //手工ACK
        channel.basicAck(deliveryTag, false);
    }
}

最后编写一个测试方法进行信息发布

    @Test
    public void send() throws Exception {
        rabbitSender.sendMsg();
    }

最终文件目录如下:
在这里插入图片描述
运行SpringBoot项目,我们先不着急进行测试,我们先进入RabbitMQ控制台,观察消费者 @RabbitListener 是否帮我们创建了对应的交换机、队列且进行了路由绑定
在这里插入图片描述
观察队列
在这里插入图片描述
点击队列查看绑定的 路由规则没问题后,我们运行测试方法,出现如下信息证明消息确认成功!
在这里插入图片描述
在这里插入图片描述
我们测试ReturnCallback仅需要修改,消息发布者的路由KEY,设置一个不存在的

//修改topicKey1.send 让其路由不到队列
 rabbitTemplate.convertAndSend("topicExchange001", "topicKey1.send","测试发送",cd);

再次运行测试类出现下面的输出证明Return成功
在这里插入图片描述

5、结语

本问主要介绍了Spring Boot 2.1.3版本的集成Spring AMQP,还是建议大家认真查阅官方的文档,了解各个组件的作用和使用方法,如果在集成过程中有任何问题,欢迎留言~谢谢大家!

6、下期预告

上一篇:消息的TTL和RabbitMQ的各种队列介绍
下一篇:Spring Boot使用Spring AMQP的消息分发和限流

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Micro麦可乐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值