整合RabbitMQ&Spring
RabbitAdmin
RabbitAdmin類可以很好的操作RabbitMQ,在spring中直接進行注入即可
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitAdmin.setAutoStartUp(true);
return rabbitAdmin;
}
- 注意:
autoStartUp必須設定為true
,否則Spring容器不會載入RabbitAdmin類 - RabbitAdmin底層實現就是從Spring容器中獲取Exchange、Bingding、RoutingKey以及Queue的@Bean方式的宣告
- 然後使用RabbitTemplate的execute方法指定對應的宣告、修改、刪除等一系列RabbitMQ基礎功能操作。
- 例如:新增一個交換機、刪除一個繫結、清空一個佇列的訊息等等就要使用的RabbitAdmin
例項:
- 新增maven依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.6.5</version>
</dependency>
- 編寫RabbitMQConfig類
package com.pyy.spring;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan({"com.pyy.spring.*"})
public class RabbitMQConfig {
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses("192.168.43.113:5672");
connectionFactory.setUsername("admin");
connectionFactory.setPassword("123456");
connectionFactory.setVirtualHost("/");
return connectionFactory;
}
@Bean
public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitAdmin.setAutoStartup(true);
return rabbitAdmin;
}
}
- 編寫測試類
@Test
public void testAdmin() {
rabbitAdmin.declareExchange(new DirectExchange("test.direct", false, false));
rabbitAdmin.declareExchange(new TopicExchange("test.topic", false, false));
rabbitAdmin.declareExchange(new FanoutExchange("test.fanout", false, false));
rabbitAdmin.declareQueue(new Queue("test.direct.queue", false));
rabbitAdmin.declareQueue(new Queue("test.topic.queue", false));
rabbitAdmin.declareQueue(new Queue("test.fanout.queue", false));
rabbitAdmin.declareBinding(new Binding("test.direct.queue",
Binding.DestinationType.QUEUE, "test.direct", "direct", new HashMap<>()));
rabbitAdmin.declareBinding(BindingBuilder.bind(
new Queue("test.topic.queue1", false)) // 直接建立佇列
.to(new TopicExchange("test.topic", false, false))// 直接建立交換機建立關係
.with("user.#"));// 直接指定路由鍵
rabbitAdmin.declareBinding(BindingBuilder.bind(
new Queue("test.topic.queue1", false)) // 直接建立佇列
.to(new FanoutExchange("test.topic", false, false)));// 直接建立交換機建立關係
}
SpringAMQP-RabbitMQ宣告式配置使用
在Rabbit基礎API裡面宣告一個Exchange、宣告一個繫結、一個佇列:
channel.exchangeDeclare(exchangeName, exchangeType, true, false, false,null);
channel.queueDeclare(queueName, false, false, false, null);
channel.queueBind(queueName, exchangeName, routingkey);
使用SpringAMQP的宣告,就需要使用SpringAMQP的如下模式,即宣告@Bean方式:
@Bean
public TopicExchange exchange() {
return new TopicExchange("topicExchange", true, false);
}
@Bean
public Queue queue() {
return new Queue("queue", true);
}
@Bean
public Binding binding() {
return new BindingBuilder.bind(queue()).to(exchange()).with("spring.*");
}
SpringAMQP訊息模板元件-RabbitTemplate實戰
RabbitTemplate, 即訊息模板
我們在與SpringAMQP整合的時候進行傳送訊息的關鍵類該類提供了豐富的傳送訊息方法,包括
可靠性訊息投遞方法
、回撥監聽訊息介面ConfirmCallback
、返回值確認介面ReturnCallback
等等。同樣我們需要進行注入到Spring容器中,然後直接使用。在與Spring整合時需要例項化,當時在與SpringBoot整合時,在配置檔案中新增配置即可。
配置注入:
@Bean
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
//rabbitTemplate.setConfirmCallback(null);
// rabbitTemplate.setReturnCallback(null);
return rabbitTemplate;
}
編寫測試類:
@Autowired
private RabbitTemplate rabbitTemplate;
@Test
public void testSendMessage() {
// 1 建立訊息
MessageProperties messageProperties = new MessageProperties();
messageProperties.getHeaders().put("desc", "資訊描述:。。。");
messageProperties.getHeaders().put("type", "自定義訊息型別");
Message message = new Message("hello Rabbitmq".getBytes(), messageProperties);
// 2 傳送訊息
rabbitTemplate.convertAndSend("test.topic.exchange", "user.#", message, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
System.out.println("------新增額外設定--------");
message.getMessageProperties().getHeaders().put("desc", "額外修改的資訊描述");
message.getMessageProperties().getHeaders().put("attr", "額外新加的描述");
return message;
}
});
}
@Test
public void testSendMessage2() {
// 1 建立訊息
MessageProperties messageProperties = new MessageProperties();
messageProperties.setContentType("text/plain");
Message message = new Message("訊息1234".getBytes(), messageProperties);
// 2 傳送訊息
rabbitTemplate.convertAndSend("test.topic.exchange", "user.#", message);
rabbitTemplate.convertAndSend("test.topic.exchange", "user.#", "hello object message send");
rabbitTemplate.convertAndSend("test.topic.exchange", "user.abc", "12234");
rabbitTemplate.send("test.topic.exchange", "user.#", message);
}
SpringAMQP訊息容器-SimpleMessageListenerContainer詳解
簡單訊息監聽容器
這個類非常的強大,我們可以對他進行很多設定,對於消費者的配置項,這個類都可以滿足
監聽佇列(多個佇列)、自動啟動、自動宣告功能
設定事務特性、事務管理器、事務屬性、事務容量(併發)、是否開啟事務、回滾訊息等
設定消費者數量、最小最大數量、批量消費配置
設定訊息確認(簽收)和自動確認模式、是否重回佇列、異常捕獲handler函式
設定消費者標籤生成策略、是否獨佔模式、消費者屬性等
設定具體的監聽器、訊息轉換器等等。
注意:
SimpleMessageListenerContainer 可以進行動態設定,比如在執行中的應用可以動態修改其消費者數量大小、接收訊息的模式等。
很多基於RabbitMQ的自定製的後端管控臺在進行動態設定的時候,也是根據這一特性實現的。所有可以看出SpringAMQP非常強大。
@Bean
public Queue queue001() {
Queue queue = new Queue("queue001", true);
return queue;
}
@Bean
public Queue queue002() {
Queue queue = new Queue("queue002", true);
return queue;
}
@Bean
public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
container.setQueues(queue001(), queue002());
container.setConcurrentConsumers(1);
container.setMaxConcurrentConsumers(5);
container.setDefaultRequeueRejected(false);
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
container.setConsumerTagStrategy(new ConsumerTagStrategy() {
@Override
public String createConsumerTag(String queue) {
return queue + "_" + UUID.randomUUID().toString();
}
});
container.setMessageListener(new ChannelAwareMessageListener() {
@Override
public void onMessage(Message message, Channel channel) throws Exception {
String msg = new String(message.getBody());
System.out.println("---消費者---" + msg);
}
});
return container;
}
思考問題:
SimpleMessageListenerContainer為什麼可以動態感知配置變更?
SpringAMQP訊息介面卡-MessageListenerAdapter使用
MessageListenerAdapter 即訊息監聽介面卡
MessageDelegate:
package com.pyy.spring;
public class MessageDelegate {
/**
* 方法名稱固定、引數型別固定
* @param messageBody
*/
public void hadnleMessage(byte[] messageBody) {
System.out.println("預設方法,訊息內容:" + new String(messageBody));
}
public void consumeMessage(byte[] messageBody) {
System.out.println("位元組陣列方法,訊息內容:" + new String(messageBody));
}
public void consumeMessage(String messageBody) {
System.out.println("字串方法,訊息內容:" + new String(messageBody));
}
}
TextConverter:
package com.pyy.spring;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.MessageConversionException;
import org.springframework.amqp.support.converter.MessageConverter;
public class TextMessageConverter implements MessageConverter {
@Override
public Message toMessage(Object object, MessageProperties messageProperties) throws MessageConversionException {
return new Message(object.toString().getBytes(), messageProperties);
}
@Override
public Object fromMessage(Message message) throws MessageConversionException {
String contentType = message.getMessageProperties().getContentType();
if(null != contentType && contentType.contains("text")) {
return new String(message.getBody());
}
return message.getBody();
}
}
RabbitConfig:
@Bean
public SimpleMessageListenerContainer messageListenerContainer(ConnectionFactory connectionFactory) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(connectionFactory);
container.setQueues(queue001(), queue002());
container.setConcurrentConsumers(1);
container.setMaxConcurrentConsumers(5);
container.setDefaultRequeueRejected(false);
container.setAcknowledgeMode(AcknowledgeMode.AUTO);
container.setConsumerTagStrategy(new ConsumerTagStrategy() {
@Override
public String createConsumerTag(String queue) {
return queue + "_" + UUID.randomUUID().toString();
}
});
// container.setMessageListener(new ChannelAwareMessageListener() {
// @Override
// public void onMessage(Message message, Channel channel) throws Exception {
// String msg = new String(message.getBody());
// System.out.println("---消費者---" + msg);
// }
// });
// 介面卡方式,預設方法名稱:handleMessage
// 可以自定義方法名稱:
// 也可以新增一個轉換器:從位元組陣列轉換為String
MessageListenerAdapter adapter = new MessageListenerAdapter(new MessageDelegate());
adapter.setDefaultListenerMethod("consumeMessage");// 設定預設監聽方法名稱
adapter.setMessageConverter(new TextMessageConverter());
container.setMessageListener(adapter);
return container;
}
- 通過messgeListenerAdapter的程式碼我們可以看出如下核心屬性:
-
defaultListenerMethod
預設監聽方法名稱:用於設定監聽方法名稱 -
Delegate
委託物件:實際真是的委託物件,用於處理訊息
SpringAMQP訊息轉換器-MessageConverter
我們在進行傳送訊息時候,正常情況下訊息體為二進位制資料方式進行傳輸,如果希望內部幫我們進行轉換,或者指定自定義的轉換器,就需要用到MessageConverter
自定義常用轉換器:
MessageConverter
,一般來講都需要實現這個介面
重寫下面兩個方法:toMessage
: java物件轉換為MessageformMessage
: Message物件轉換為java物件Json轉換器:
Jackson2JsonMessageConverter
:可以進行java物件的轉換功能DefaultJackson2JavaTypeMapper
對映器:可以進行java物件的對映關係自定義二進位制轉換器:比如圖片型別、PDF、PPT、流媒體
相關文章
- 整合持續整合工具
- 【springboot】學習4:整合JDBC、整合druid、整合mybatis、整合 SpringSecuritySpring BootJDBCUIMyBatisGse
- SpringBoot整合系列-整合JPASpring Boot
- MyBatis(九) 整合Spring、整合SpringMVCMyBatisSpringMVC
- SSM整合之CRUD環境搭建整合SSM
- ssm整合SSM
- SpringBoot整合系列-整合H2Spring Boot
- RestCloud iPaaS混合整合平臺,資料整合RESTCloud
- SpringBoot整合系列–整合MyBatis-plusSpring BootMyBatis
- 整合學習(一):簡述整合學習
- SSH框架整合配置所需JAR包(SSH整合)框架JAR
- 自動化整合:Pipeline整合Docker容器Docker
- ETL資料整合,RestCloud資料整合平臺RESTCloud
- Win10整合Cortana,Mac何時整合Siri?Win10Mac
- Spring AI與大模型Ollama如何整合整合?SpringAI大模型
- Vue整合UeditorVue
- SSM框架整合SSM框架
- Vuex之整合Vue
- CodePush整合
- 整合SSM框架SSM框架
- Spark整合hiveSparkHive
- Vitis AI 整合AI
- SSH框架整合框架
- OpenStack整合DockerDocker
- QTP整合SikuliQT
- 系統整合
- 整合SwiftLintSwift
- 整合學習
- SSM學習筆記3——整合 SpringMVC、整合SSMSSM筆記SpringMVC
- Mybatis整合Spring(ssm整合待續)-day04MyBatisSpringSSM
- API整合新一代平臺,iPaaS整合平臺API
- 企業如何資料整合?資料整合解決方案
- 五個模型整合模型
- Spring 整合 MyBatisSpringMyBatis
- SSM整合開發SSM
- SpringMVC整合MybatisSpringMVCMyBatis
- 資料庫整合資料庫
- Prometheus 整合 Node ExporterPrometheusExport