目錄
前言
Spring Boot 支持 JMS 和 AMQP 的異步消息。JMS(Java Message Service) 即Java消息服務,是基於JVM消息代理的規範,JMS的實現有:ActiveMQ、HornetQ;AMQP(Advanced Message Queuing Protocol) 也是一個消息代理的規範,不僅兼容JMS,還支持跨語言和平臺,AMQP的實現有RabbitMQ。
本篇文章就來看看Spring Boot 中如何使用 RabbitMQ。
異步消息
首先來說說什麼是異步消息,異步消息主要目的是爲了系統與系統之間的通信。所謂異步消息即消息發送者無需等待消息接受者的處理及返回,甚至無需關係消息是否發送成功。
在異步消息中有兩個 重要的概念:消息代理(message borker)和目的地(destination),當消息發送者發送消息後,消息將由消息代理接管,消息代理保證消息傳遞到指定的目的地。異步消息主要有兩種形式的目的地:隊列(queue)和主題(topic)。隊列用於點對點的消息通信;主題用於發佈/訂閱式的消息通信。
一、點對點式
當消息發送者發送消息,消息代理獲得消息後將消息放進隊列中,當有消息接受者來接受消息時,消息將從隊列中取出來傳遞給接受者,這個時候隊列就沒有了這條消息。
點對點式確保的是每一條消息只有唯一的生產者和消費者,當然,這並不是說只有一個接受者可以從隊列中接受消息。因爲隊列中有很多消息,點對點式只保證每一條消息只有唯一的生產者和消費者。
二、發佈/訂閱式
和點對點式不同,發佈/訂閱式是消息發送者發送消息到主題(topic),而多個接受者監聽這個主題,此時消息發送者和接受者分別叫叫做發佈者和訂閱者。
Spring Boot集成RabbitMQ
一、添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
二、配置RabbitMQ
1、在application.properties中配置RabbitMQ的連接信息,如下圖。
spring.rabbitmq.host=localhost
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
2、聲明Exchange、Queue、Binding等信息,爲了聲明方便,我們提前定義好隊列常量信息,如下圖。
/**
* 隊列常量信息
*/
public interface QueueConstants {
/**
* 消息交換
*/
String MESSAGE_EXCHANGE = "spring.boot.message.direct.exchange";
/**
* 消息隊列名稱
*/
String MESSAGE_QUEUE_NAME = "message.queue";
/**
* 消息路由鍵
*/
String MESSAGE_ROUTE_KEY = "message.send";
}
@Configuration
public class RabbitConfig {
/**
* 交換機配置
* @return
*/
@Bean
public DirectExchange addDirectExchange(){
return (DirectExchange)ExchangeBuilder.directExchange(QueueConstants.MESSAGE_EXCHANGE)
.durable(true)
.build();
}
/**
* 消息隊列聲明
* @return
*/
@Bean
public Queue addQueue(){
return QueueBuilder.durable(QueueConstants.MESSAGE_QUEUE_NAME).build();
}
/**
* 消息綁定
* @return
*/
@Bean
public Binding messageBinding(){
return BindingBuilder.bind(addQueue())
.to(addDirectExchange())
.with(QueueConstants.MESSAGE_ROUTE_KEY);
}
}
三、定義消息實體
/**
* 消息實體
*/
public class MessageEntity implements Serializable {
private static final long serialVersionUID = 296763681597798722L;
private String contents;
//get、set方法略
}
四、定義生產者
生產者即消息發送者,需要注入AmqpTemplate用來發送消息,如下圖。
/**
* 生產者(消息發送者)
*/
@Component
public class Provider {
@Autowired
private AmqpTemplate rabbitTemplate;
/**
* 發送消息
* @param object
*/
public void send(Object object){
System.out.println("Sender : " + JSON.toJSONString(object));
this.rabbitTemplate.convertAndSend(QueueConstants.MESSAGE_EXCHANGE, QueueConstants.MESSAGE_ROUTE_KEY, object);
}
}
五、定義消費者
消費者即消息接受者,通過@RabbitListener註解定義要監聽的消息隊列,用@RabbitHandler定義消息處理方法。
/**
* 消費者(消息接受者)
*/
@Component
@RabbitListener(queues = QueueConstants.MESSAGE_QUEUE_NAME)
public class Receiver {
/**
* 接受消息
* @RabbitHandler會自動獲取消息
* @param messageEntity
*/
@RabbitHandler
public void handler(@Payload MessageEntity messageEntity){
System.out.println("Receiver : " + JSON.toJSONString(messageEntity));
}
}
六、驗證
一如既往,我們還是用web請求的方法來驗證,定義Controller如下:
@RestController
@RequestMapping("/rabbitmq")
public class MessageController {
@Resource
private Provider provider;
@RequestMapping("/send")
public String send(MessageEntity message){
provider.send(message);
return "success";
}
}
驗證結果如下: