SpringBoot+RabbitMQ完成應(yīng)用通信
應(yīng)用通信
作為?個(gè)消息隊(duì)列, RabbitMQ也可以?作應(yīng)?程序之間的通信. 上述代碼?產(chǎn)者和消費(fèi)者代碼放在不同的應(yīng)?中即可完成不同應(yīng)?程序的通信.
接下來(lái)我們來(lái)看, 基于SpringBoot+RabbitMQ完成應(yīng)?間的通信.
需求描述
??下單成功之后, 通知物流系統(tǒng), 進(jìn)?發(fā)貨。

訂單系統(tǒng)作為?個(gè)?產(chǎn)者, 物流系統(tǒng)作為?個(gè)消費(fèi)者。
創(chuàng)建項(xiàng)目
創(chuàng)建空項(xiàng)目

創(chuàng)建Module(order-service)


添加依賴

創(chuàng)建Module(logistics-service)

添加依賴

消息類型為字符串
編寫訂單代碼
添加配置
spring:
application:
name: order-service
rabbitmq:
addresses: amqp://study:study@47.98.109.138:5672/order聲明隊(duì)列
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Bean("orderQueue")
public Queue orderQueue() {
return QueueBuilder.durable("order.create").build();
}
}生產(chǎn)訂單
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Random;
import java.util.UUID;
@RequestMapping("/order")
@RestController
public class OrderController {
@Autowired
private RabbitTemplate rabbitTemplate;
@RequestMapping("create")
public String create(){
String orderId= UUID.randomUUID().toString();
rabbitTemplate.convertAndSend("","order.create","訂單信息,訂單ID:"+orderId);
return "下單成功";
}
}編寫物流代碼
添加配置
spring:
application:
name: logistics-service
rabbitmq:
addresses: amqp://study:study@47.98.109.138:5672/order
server:
port: 9090聲明隊(duì)列
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Bean("order.create")
public Queue createOrder() {
return QueueBuilder.durable("order.create").build();
}
}消費(fèi)訂單
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class OrderListener {
@RabbitListener(queues = "order.create")
public void handMessage(String orderInfo) {
System.out.println("接收到訂單消息"+orderInfo);
}
}生產(chǎn)訂單


消費(fèi)訂單


可以看到,訂單已經(jīng)被成功消費(fèi)了,結(jié)果符合預(yù)期。
消息類型為對(duì)象
下面的代碼是以上面代碼的基礎(chǔ),并進(jìn)行增添刪除編寫而成的。
新增Module
因?yàn)橛唵蜗到y(tǒng)和物流系統(tǒng)在生產(chǎn)和消費(fèi)對(duì)象類型的消息時(shí),會(huì)用到同一個(gè)結(jié)構(gòu)體,為了便于代碼編寫,新增Module,把OrderInfo放到新增的Module中。



import lombok.Data;
@Data
public class OrderInfo{
private String orderId;
private String name;
}
編寫訂單代碼
在order-service項(xiàng)目的OrderController中添加如下代碼:
@RequestMapping("create2")
public String create2(){
OrderInfo orderInfo=new OrderInfo();
orderInfo.setOrderId(UUID.randomUUID().toString());
orderInfo.setName("商品"+new Random().nextInt(100));
rabbitTemplate.convertAndSend("","order.create",orderInfo);
return "下單成功";
}生產(chǎn)對(duì)象類型訂單消息


此時(shí)我們發(fā)現(xiàn)拋異常了,異常信息為SimpleMessageConverter只支持String, byte[] and Serializable類型的payloads,但是接收到的是order.model.OrderInfo對(duì)象。
解決辦法1(實(shí)現(xiàn)序列化接口)
修改order-service下的OrderInfo類
import lombok.Data;
import java.io.Serializable;
@Data
public class OrderInfo implements Serializable {
private String orderId;
private String name;
}


雖然成功生成了對(duì)象類型的訂單消息,但是我們看到消息的Payload并不直觀,下面我們將采用兩一種解決辦法。
解決辦法2(設(shè)置消息轉(zhuǎn)換類型)
修改order-service中的OrderInfo
import lombok.Data;
@Data
public class OrderInfo{
private String orderId;
private String name;
}查看RabbitTemplated的setMessageConverter方法,查看MessageConverter接口的實(shí)現(xiàn)類,我們將使用Jackson2JsonMessageConverter。

修改order-service中的RabbitMQConfig
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Bean("orderQueue")
public Queue orderQueue() {
return QueueBuilder.durable("order.create").build();
}
@Bean
public Jackson2JsonMessageConverter jsonMessageConverter(){
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory factory, Jackson2JsonMessageConverter jsonMessageConverter){
RabbitTemplate rabbitTemplate = new RabbitTemplate(factory);
rabbitTemplate.setMessageConverter(jsonMessageConverter);
return rabbitTemplate;
}
}再次生產(chǎn)對(duì)象類型訂單消息



此時(shí)再次查看隊(duì)列中的消息,我們可以看到消息的Payload是非常直觀的?。?!
編寫物流代碼
修改logistics-service中的代碼
import logistics.model.OrderInfo;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@RabbitListener(queues = "order.create")
public class OrderListener {
public void handMessage(String orderInfo) {
System.out.println("接收到訂單消息"+orderInfo);
}
public void handMessage(OrderInfo orderInfo) {
System.out.println("接收到訂單消息"+orderInfo);
}
}消費(fèi)對(duì)象類型訂單消息


但是過(guò)了許久,我們也沒(méi)有看到隊(duì)列中的消息被消費(fèi)?。?!
解決辦法
原因是因?yàn)锧RabbitListener(queues = "order.create")注解聲明在類上面時(shí),須結(jié)合@RabbitHandler注解來(lái)使用?。?!
修改logistics-service中的代碼
import logistics.model.OrderInfo;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
@RabbitListener(queues = "order.create")
public class OrderListener {
@RabbitHandler
public void handMessage(String orderInfo) {
System.out.println("接收到訂單消息"+orderInfo);
}
@RabbitHandler
public void handMessage(OrderInfo orderInfo) {
System.out.println("接收到訂單消息"+orderInfo);
}
}此時(shí)消費(fèi)消息,但是發(fā)現(xiàn)又拋異常了


原因是因?yàn)椋覀兊拇_是針對(duì)生產(chǎn)對(duì)象類型消息的一方設(shè)置了MessageConverter,但是我們沒(méi)有給消費(fèi)對(duì)象類型消息的一方設(shè)置MessageConverter,導(dǎo)致消費(fèi)對(duì)象類型消息的一方?jīng)]有辦法正確解析出消息。
解決辦法,依舊是添加MessageConverter!?。?/p>
修改logistics-service中的RabbitMQConfig
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Bean("order.create")
public Queue createOrder() {
return QueueBuilder.durable("order.create").build();
}
@Bean
public Jackson2JsonMessageConverter jsonMessageConverter(){
return new Jackson2JsonMessageConverter();
}
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory factory, Jackson2JsonMessageConverter jsonMessageConverter){
RabbitTemplate rabbitTemplate = new RabbitTemplate(factory);
rabbitTemplate.setMessageConverter(jsonMessageConverter);
return rabbitTemplate;
}
}再次消費(fèi)消息

此時(shí)我們可以看到,對(duì)象類型的訂單消息可以正常消費(fèi)了,符合預(yù)期。
到此這篇關(guān)于SpringBoot+RabbitMQ完成應(yīng)用通信的文章就介紹到這了,更多相關(guān)SpringBoot RabbitMQ通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot集成rabbitMQ之對(duì)象傳輸?shù)姆椒?/a>
- springboot實(shí)現(xiàn)rabbitmq的隊(duì)列初始化和綁定
- SpringBoot+RabbitMq具體使用的幾種姿勢(shì)
- SpringAMQP消息隊(duì)列(SpringBoot集成RabbitMQ方式)
- SpringBoot中RabbitMQ集群的搭建詳解
- 一文掌握Springboot集成RabbitMQ的方法
- Springboot 配置RabbitMQ文檔的方法步驟
- springboot整合rabbitmq的示例代碼
- SpringBoot 整合 RabbitMQ 的使用方式(代碼示例)
相關(guān)文章
SpringBoot統(tǒng)一返回結(jié)果問(wèn)題
這篇文章主要介紹了SpringBoot統(tǒng)一返回結(jié)果問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07
Java并發(fā)編程之詳解ConcurrentHashMap類
在之前的文章中已經(jīng)為大家介紹了java并發(fā)編程的工具:BlockingQueue接口、ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue、BlockingDeque接口,本文為系列文章第八篇.需要的朋友可以參考下2021-06-06
java 實(shí)現(xiàn)讀取txt文本數(shù)據(jù)并以數(shù)組形式一行一行取值
今天小編就為大家分享一篇java 實(shí)現(xiàn)讀取txt文本數(shù)據(jù)并以數(shù)組形式一行一行取值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
Java實(shí)現(xiàn)登錄密碼強(qiáng)度校驗(yàn)的項(xiàng)目實(shí)踐
本文主要介紹了Java實(shí)現(xiàn)登錄密碼強(qiáng)度校驗(yàn)的項(xiàng)目實(shí)踐,包括使用正則表達(dá)式匹配校驗(yàn)和密碼強(qiáng)度校驗(yàn)工具類這兩種方法,具有一定的參考價(jià)值,感興趣的可以了解一下2024-01-01
Java?生成透明圖片的設(shè)置實(shí)現(xiàn)demo
這篇文章主要為大家介紹了Java?生成透明圖片的設(shè)置實(shí)現(xiàn)demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
vscode快速引入第三方j(luò)ar包發(fā)QQ郵件
這篇文章主要介紹了vscode快速引入第三方j(luò)ar包發(fā)QQ郵件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
springMVC之HandlerExceptionResolver使用
這篇文章主要介紹了springMVC之HandlerExceptionResolver使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11

