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
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(); } }
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"; } }
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); } }