1. 程式人生 > >隨便談談RabbitMQ與springBoot進行整合。

隨便談談RabbitMQ與springBoot進行整合。

先說說題外話,本來只想找到一個springBoot快速整合RabbitMQ的例子,用起來就行的。但是百度搜了一大通, 各有各的玩法,但是就是沒找到一個自己心儀的方式。最終發現,稍微看看springBoot的jar包,頓時覺得清晰好多。

順便說明一下,這個文章全是我自己總結的,目前是不同於網路上各種轉載文的。旨在給有興趣的朋友共同分享。

關於RabbitMQ就不做介紹了。幾種訊息傳遞模式官網自有介紹。這裡只關注兩個點:
1、如何主動傳送及消費訊息。
2、如何註冊監聽自動消費發過來的訊息。

首先針對第一個問題:
springBoot已經有了整合rabbitMQ 的 starter

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

加入這個引用後,就可以在springBoot的配置檔案中直接配置rabbitMQ的屬性,(以spring.rabbitmq開頭)然後在自己的方法中可以注入 RabbitTemplate ,用這個template進行發訊息 以及 收訊息 的操作 。可以設定exchange ,routekey,queue什麼的,然後一大堆的send receive方法可以呼叫。
是不是覺得有點太簡單了?這用法比百度搜到的大部分示例都簡單,甚至都不用上示例程式碼。那下面就一起來看看是怎麼回事唄。

可以看到 引入了maven依賴後,springBoot的自動配置模組就已經引入進來了,正是在這裡面封裝了springBoot對RabbitMQ的配置。在spring-boot-autoconfigure模組中有RabbitMQ 的自定義配置載入類
SpringBoot對RabbitMQ的自動配置類

這個類在META-INF下的spring.factories檔案中已經配置成了在springBoot啟動時就會自動進行配置。這是springBoot的自動配置機制。
spring.factories配置片段
然後在這個配置類的程式碼頭部可以看到配置的要求
註釋宣告
同時,這個配置類往spring容器裡注入了幾個Bean。
這裡寫圖片描述

這裡寫圖片描述

其中,這個RabbitTemplate就是可以用來操作RabbitMQ的一個重要的工具類。
這樣,在自己的程式碼中,就可以直接用@Resource或者@Autowire引用這個類來發送及接受訊息了。

而RabbitProperties就是rabbit的相關配置的處理類。
這裡寫圖片描述
所以,只要在application.properties裡配置spring.rabbitmq開頭的幾個屬性,就會自動配置到這些類裡。
至於spring.rabbitmq下可選的配置屬性, 在spring-boot-autoconfigure包下的/META-INF/spring-configuration-metadata.json 檔案中有詳細的定義。用IDEA就會自動彈出所有可選的配置項。eclipse貌似不行。–其實這些註釋都是通過RabbitProperties來注入的,看看這個類的屬性也能知道要配些什麼東西。
這裡寫圖片描述

分析到這裡,通過SpringBoot主動傳送和接受訊息的引入方式就已經知道了。

然後針對第二個問題:
繼續看看怎麼用springBoot的方式註冊監聽,自動消費發過來的訊息。
還是在那個 自動註冊類 RabbitAutoConfiguration裡,可以看到頭部還引用了一個配置類 RabbitAnnotationDrivenConfiguration 從名字就看出這是Rabbit的註釋驅動配置類,一看就是springBoot的風格。還是看頭部的宣告
這裡寫圖片描述
這個配置需要有EnableRabbit註釋才會啟動配置。然後,看看這個EnableRabbit 註釋前面的註釋內容就很一目瞭然了

org.springframework.amqp.rabbit.annotation.EnableRabbit

Enable Rabbit listener annotated endpoints that are created under the
cover by a RabbitListenerContainerFactory. To be used on
Configuration classes as follows: @Configuration @EnableRabbit
public class AppConfig {
@Bean
public SimpleRabbitListenerContainerFactory myRabbitListenerContainerFactory() {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory());
factory.setMaxConcurrentConsumers(5);
return factory;
}
// other @Bean definitions } The RabbitListenerContainerFactory is responsible to create the listener container responsible for a
particular endpoint. Typical implementations, as the
SimpleRabbitListenerContainerFactory used in the sample above,
provides the necessary configuration options that are supported by
the underlying MessageListenerContainer.

@EnableRabbit enables detection of RabbitListener annotations on any
Spring-managed bean in the container. For example, given a class
MyService: package com.acme.foo;

public class MyService {
@RabbitListener(containerFactory=”myRabbitListenerContainerFactory”,
queues=”myQueue”)
public void process(String msg) {
// process incoming message
} } The container factory to use is identified by the containerFactory attribute defining the name of the
RabbitListenerContainerFactory bean to use. When none is set a
RabbitListenerContainerFactory bean with name
rabbitListenerContainerFactory is assumed to be present. the
following configuration would ensure that every time a
org.springframework.amqp.core.Message is received on the
org.springframework.amqp.core.Queue named “myQueue”,
MyService.process() is called with the content of the message:
@Configuration @EnableRabbit public class AppConfig {
@Bean
public MyService myService() {
return new MyService();
}

 // Rabbit infrastructure setup  } Alternatively, if MyService were annotated with  @Component, the following configuration would

ensure that its @RabbitListener annotated method is invoked with a
matching incoming message: @Configuration @EnableRabbit
@ComponentScan(basePackages=”com.acme.foo”) public class AppConfig {
} Note that the created containers are not registered against the
application context but can be easily located for management purposes
using the RabbitListenerEndpointRegistry.

Annotated methods can use flexible signature; in particular, it is
possible to use the Message abstraction and related annotations, see
RabbitListener Javadoc for more details. For instance, the following
would inject the content of the message and a a custom “myCounter”
AMQP header: @RabbitListener(containerFactory =
“myRabbitListenerContainerFactory”, queues = “myQueue”) public void
process(String msg, @Header(“myCounter”) int counter) {
// process incoming message } These features are abstracted by the MessageHandlerMethodFactory that is responsible to build the
necessary invoker to process the annotated method. By default,
DefaultMessageHandlerMethodFactory is used. When more control is
desired, a @Configuration class may implement
RabbitListenerConfigurer. This allows access to the underlying
RabbitListenerEndpointRegistrar instance. The following example
demonstrates how to specify an explicit default
RabbitListenerContainerFactory @Configuration
@EnableRabbit public class AppConfig implements
RabbitListenerConfigurer {
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setContainerFactory(myRabbitListenerContainerFactory());
}

 @Bean
 public RabbitListenerContainerFactory myRabbitListenerContainerFactory() {
     // factory settings
 }

 @Bean
 public MyService myService() {
     return new MyService();
 }  }  } For reference, the example above can be compared to the following Spring  XML configuration:   <beans>
 <rabbit:annotation-driven container-factory="myRabbitListenerContainerFactory"/>

 <bean id="myRabbitListenerContainerFactory"
       class="org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory">
       // factory settings
 </bean>

 <bean id="myService" class="com.acme.foo.MyService"/>  </beans> It is also possible to specify a custom RabbitListenerEndpointRegistry

in case you need more control on the way the containers are created
and managed. The example below also demonstrates how to customize the
RabbitHandlerMethodFactory to use with a custom Validator so that
payloads annotated with Validated are first validated against a
custom Validator. @Configuration @EnableRabbit public
class AppConfig implements RabbitListenerConfigurer {
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
registrar.setEndpointRegistry(myRabbitListenerEndpointRegistry());
registrar.setMessageHandlerMethodFactory(myMessageHandlerMethodFactory);
}

 @Bean
 public RabbitListenerEndpointRegistry myRabbitListenerEndpointRegistry() {
     // registry configuration
 }

 @Bean
 public RabbitHandlerMethodFactory myMessageHandlerMethodFactory() {
    DefaultRabbitHandlerMethodFactory factory = new DefaultRabbitHandlerMethodFactory();
    factory.setValidator(new MyValidator());
    return factory;
 }

 @Bean
 public MyService myService() {
     return new MyService();
 }  }  } For reference, the example above can be compared to the following Spring  XML configuration:   <beans>
 <rabbit:annotation-driven registry="myRabbitListenerEndpointRegistry"
     handler-method-factory="myRabbitHandlerMethodFactory"/&gt;

 <bean id="myRabbitListenerEndpointRegistry"
       class="org.springframework.amqp.rabbit.config.RabbitListenerEndpointRegistry">
       // registry configuration
 </bean>

 <bean id="myRabbitHandlerMethodFactory"
       class="org.springframework.amqp.rabbit.config.DefaultRabbitHandlerMethodFactory">
     <property name="validator" ref="myValidator"/>
 </bean>

 <bean id="myService" class="com.acme.foo.MyService"/>  </beans> Implementing RabbitListenerConfigurer  also allows for fine-grained

control over endpoints registration via the
RabbitListenerEndpointRegistrar. For example, the following
configures an extra endpoint: @Configuration @EnableRabbit public
class AppConfig implements RabbitListenerConfigurer {
@Override
public void configureRabbitListeners(RabbitListenerEndpointRegistrar registrar) {
SimpleRabbitListenerEndpoint myEndpoint = new SimpleRabbitListenerEndpoint();
// … configure the endpoint
registrar.registerEndpoint(endpoint, anotherRabbitListenerContainerFactory());
}

 @Bean
 public MyService myService() {
     return new MyService();
 }

 @Bean
 public RabbitListenerContainerFactory anotherRabbitListenerContainerFactory() {
     // ...
 }

 // Rabbit infrastructure setup  }  } Note that all beans implementing RabbitListenerConfigurer  will be detected and invoked in

a similar fashion. The example above can be translated in a regular
bean definition registered in the context in case you use the XML
configuration.

Since:
1.4 Author: Stephane Nicoll See Also: RabbitListener RabbitListenerAnnotationBeanPostProcessor
org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar
org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistry

裡面很多詳細的配置,可以逐步的設定預設的處理流程。有興趣可以再繼續深入跟蹤下去。
(網上看到有一個教程,說對ConnectionFactory,因為沒有預設設定來支援訊息回撥 connectionFactory.setPublisherConfirms(true);
而大費周章,擯棄springBoot的自動配置,自己從頭注入。雖然沒有動手試過,但是看著些說明,springBoot都是有很優雅的方式支援設定的。)

所以最後,針對第二個問題,結果也就出來了。
最簡單的用法就是按註釋裡說的分三步
先定義一個SimpleRabbitListenerContainerFactory

 @Configuration
 @EnableRabbit
 public class AppConfig {
     @Bean
     public SimpleRabbitListenerContainerFactory myRabbitListenerContainerFactory() {
       SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
       factory.setConnectionFactory(connectionFactory());
       factory.setMaxConcurrentConsumers(5);
       return factory;
     }
     // other @Bean definitions
 }

然後就可以定義自己的service監聽這個連線發過來的訊息了。

 package com.acme.foo;

 public class MyService {
     @RabbitListener(containerFactory="myRabbitListenerContainerFactory", queues="myQueue")
     public void process(String msg) {
         // process incoming message
     }
 }

然後把這個MyService注入到spring容器裡

@Configuration
 @EnableRabbit
 public class AppConfig {
     @Bean
     public MyService myService() {
         return new MyService();
     }

     // Rabbit infrastructure setup
 }

相關推薦

隨便談談RabbitMQspringBoot進行整合

先說說題外話,本來只想找到一個springBoot快速整合RabbitMQ的例子,用起來就行的。但是百度搜了一大通, 各有各的玩法,但是就是沒找到一個自己心儀的方式。最終發現,稍微看看springBoot的jar包,頓時覺得清晰好多。 順便說明一下,這個文

springbootjunit進行整合

springboot與junit進行整合 引入junit的起步依賴 <!--測試的起步依賴--> <dependency> <groupId>org.springframework.boot</groupId>

RabbitMQ ——SpringBoot整合並實現訊息確認機制

不囉嗦直接上程式碼 目錄結構如下: pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instanc

cas4.2.7shiro進行整合

exce cor lec ces nco Coding schema enc pattern 準備工作   cas單點登錄開始前準備,請參考cas4.2.7實現單點登錄。 與shiro進行整合   註:準備工作的基礎上,對cas客戶端進行如下改進。   引入相關ja

JMeter 如何 MySQL 進行整合測試

做效能測試定位瓶頸的時候,定位到是因為某些 SQL 語句的查詢慢所影響的,此時我們提出優化方案,肯定希望驗證下優化後的 SQL,此時需要藉助 JMeter 的 JDBC 請求,那麼我們就需要學習 JMeter 如何與 MySQL 進行整合測試。 環境準備 除了 JMeter 外,還需要

JMeter MySQL 進行整合測試 ?

做效能測試定位瓶頸的時候,定位到是因為某些 SQL 語句的查詢慢所影響的,此時我們提出優化方案,肯定希望驗證下優化後的 SQL,此時需要藉助 JMeter 的 JDBC 請求,那麼我們就需要學習 JMeter 如何與 MySQL 進行整合測試。   環境準備 除了 JMeter

ActiveMQSpring進行整合

                                ActiveMQ與Spring進行整合   Activ

如何將Flumekafka進行整合

自從Flume1.6開始,新增了對Kafka的支援,極大地提升了Flume的採集能力。避免後端因熱點問題導致kafka的channel爆滿而無法採集資料。 本篇介紹使用Flume當前最新版本1.8與Kafka的結合使用。基本環境Kafka (192.168.156.101:9092)Zookeeper(192

ElasticSearchSpringBoot整合JPA方法的使用

完整程式碼示例,請參考個人GitHub倉庫:(github.com/KimZing), 包含controller/repository以及測試程式碼。 歡迎star,如有錯誤,歡迎指正_ 一、環境簡介 idea 2016.3 jdk 1.8 ElasticSearch 2.4(之所以不用最

讓Struts2Spring進行整合原因及原理

Struts2與Spring進行整合的根本目的就是要讓 Spring為Struts2的Action注入所需的資源物件,它們整合的原理則是隻要匯入了struts2的spring外掛包,不需要進行任何額外的配置,Struts2的Action例項物件將由struts2的spr

thinkphp3.2【控制器呼叫檢視view模板&檢視模板專案進行整合

【控制器呼叫檢視view模板】 控制器----》檢視   APP_DEBUG = true;  除錯模式錯誤資訊顯示更詳細   控制器和模板的關係 通常:在view目錄通常會有一個與控制器標誌一樣的目錄,裡邊有具體模板檔案 例如GoodsController.clas

swagger springboot整合實戰

說明:這篇筆記參考了下面的部落格,感謝博主。 第 1 步: 引入相關的依賴。 <dependency> <groupId>com.mangofactory</groupId> <artifactId&

IDEA開發環境中,SpringMVCSwagger2的整合完成restful風格的API開發

專案結構Swapper2在POM中的依賴<!-- springfox依賴 --> <dependency> <groupId>io.springfox</groupId> <artifactId>sp

intellij ideagit/github整合

一,到github官網註冊賬號 二,建立一個倉庫: 例如 AOP 三,安裝 github for windows 客戶端 四,初始化本地git倉庫 從剛剛安裝好的 "github for windows" 中開啟命令終端Git Shell: 進入你的intellij

將zookeeper curatorspringboot專案進行整合(重點)

第一步:用java類進行配置 package com.lpy; import org.apache.curator.RetryPolicy; import org.apache.curator.framework.CuratorFramework; import org.apache.curat

RabbitMQ映象佇列叢集搭建、SpringBoot整合

映象模式 叢集模式非常經典的就是Mirror映象模式,保證100%資料不丟失,在實際工作中也是用的最多的,並且實現叢集比較的簡單。 Mirror映象佇列,目的是為了保證 RabbitMQ 資料的高可靠性解決方案,主要就是實現資料的同步,一般來講2--3個節點實現資料同步(對於100%資料可靠性解決方案一般是3

SpringbootMyBatis簡單整合

方法 jar 啟動 over resultmap prop toc 系統 服務器 之前搭傳統的ssm框架,配置文件很多,看了幾天文檔才把那些xml的邏輯關系搞得七七八八,搭起來也是很麻煩,那時我完全按網上那個demo的版本要求(jdk和tomcat),所以最後是各種問題沒成

編寫一個程序,將 a.txt 文件中的單詞 b.txt 文件中的單詞交替合並到 c.txt 文件中,a.txt 文件中的單詞用回車符分隔,b.txt 文件中用回車或空格進行分隔

程序 AD res exception oid lin spl 一個 path import java.io.BufferedReader; import java.io.FileInputStream; import java.io.InputStreamReader;

SpringBoot28 RabbitMQ知識點、Docker下載RabbitMQSpringBoot整合RabbtiMQ

wired provide 進行 prop oca key plugin sim clu 1 RabbitMQ知識點   1.1 整體架構圖     消息生產者將消息投遞到exchange中,exchange會以某種路由機制將生產者投遞的消息路由到queue中,消息消費

springboot簡易整合rabbitmq

寫在前面:本文采用rabbitmq環境是docker單節點。 專案地址:https://github.com/Blankwhiter/AMQP 一、搭建rabbitmq環境 在centos視窗中,執行如下命令拉取映象,以及建立容器: docker pull rabbitmq:3.