RabbitMQ------整合SpringAMQP

一。什么是Spring-AMQP?

1.Spring框架的AMQP消息解决方案,提供模板化的发送和接收消息的抽象层,提供基于消息驱动的POJO(Plain Ordinary Java Object 简单的Java对象)的消息监听等

2.提供不依赖于任何特定的AMQP代理实现或客户端库通用的抽象,最终用户代码将很容易实现更易替换、添加和删除AMQP,因为它可以只针对抽象层来开发

 

二。代码(以topic模式举例)

1.添加pom.xml依赖

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

 

2.修改applicatio.yml配置

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: 123456
    #虚拟主机 可在http://localhost:15672管理平台进行配置
    virtual-host: /dev
    #开启消息二次确认ConfirmCallback配置
    publisher-confirms: true
    #开启ReturnCallback配置
    publisher-returns: true
    #修改交换机改投消息递到队列失败策略
    #true:交换机处理消息到队列失败,则返回给生产者
    template:
      mandatory: true
    #消息手工确认ack
    listener:
      simple:
        acknowledge-mode: manual
View Code

 

3.添加RabbitMQConfig.java代码

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

/**
 * Rabbitmq配置类
 *
 * */
@Configuration
public class RabbitmqConfig {

    public static final String EXCHANGE_NAME = "order_exchange";
    public static final String QUEUE_NAME = "order_queue";

    /**
     * 交换机(topic模式)
     *
     * */
    @Bean
    public Exchange orderExchange(){
        //durable: 是否持久化, 队列的声明默认是存放到内存中的,如果rabbitmq重启会丢失,
        // 如果想重启之后还存在就要使队列持久化,保存到Erlang自带的Mnesia数据库中,
        // 当rabbitmq重启之后会读取该数据库
        return ExchangeBuilder.topicExchange(EXCHANGE_NAME).durable(true).build();
    }

    /**
     * 队列
     *
     * */
    @Bean
    public Queue orderQueue() {
        return QueueBuilder.durable(QUEUE_NAME).build();
    }

    /**
     * 绑定交换机和队列
     *
     * */
    @Bean
    public Binding orderBinding(Exchange exchange, Queue queue){
        return BindingBuilder.bind(queue).to(exchange).with("order.#").noargs();
    }
}
View Code

 

4.添加消息生产者代码

@RestController
@RequestMapping("/user-info")
public class UserInfoController {

    @Autowired
    public RedisTemplate redisTemplate;  

    //消息生产者
    @GetMapping("/send")
    public String testSend(){
        rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_NAME, "order.new", "新订单消息");
        return "success";
    }
}
View Code

 

5.添加消息消费者代码

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
@RabbitListener(queues = "order_queue")
public class OrderMQListener {

    /**
     * body: 接收onvertAndSend(String exchange, String routingKey, Object object)的order消息
     *
     * */
    @RabbitHandler
    public void messageHandler(String body, Message message, Channel channel) throws IOException {

        long msgTag = message.getMessageProperties().getDeliveryTag();
        System.out.println("body: " + body);
        System.out.println("msgTag: " + msgTag);
        System.out.println("message: " + message.toString());

        //告诉broker(消息队列服务器实体),消息已经被确认
        channel.basicAck(msgTag, false);
        //告诉broker,消息拒绝确认(可以拒绝多条,把比当前msgTag值小的也拒绝)
//        channel.basicNack(msgTag, false, true);
        //告诉broker,消息拒绝确认(只能拒绝当前msgTag的这条)
//        channel.basicReject(msgTag, true);
    }
}
View Code

 

posted @ 2021-09-27 10:08  玉天恒  阅读(119)  评论(0编辑  收藏  举报