【RabbitMQ消息中間件】10.Spring-Rabbit項目剖析

版權聲明:本文爲博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接和本聲明。
本文連接:https://blog.csdn.net/u013517797/article/details/79601121
以前咱們詳細介紹了RabbitMQ而且講解了其5中隊列模式,在期間編寫了許多小例子。可是在真實的開發階段,咱們不多使用以前編寫Demo時的編寫方式,一個是不方便,一個是難以維護。因此,在企業級的開發中,通常是結合框架來進行開發的。java

1、spring-rabbit項目介紹
在Java開發中,RabbitMQ的開發天然少不了與Spring框架的結合。本篇咱們就來了解一下,Spring爲咱們提供的與RabbitMQ向結合的開源樣例工程「Spring-Rabbit」,經過了解該開源工程,咱們能夠更加了解在實際開發中如何結合Spring來進行RabbitMQ業務的開發。web

在Spring的官方網站「spring.io」中,咱們能夠看到spring團隊發佈的與spring相關的歷屆以及最新的框架產品:spring

 

 

而本此咱們要了解的,就是spring框架對AMQP協議的支持,便是「spring AMQP」的相關產品:apache

 

 

 

點擊進去以後,能夠看到該開源項目的詳細介紹:mybatis

 

 

 

 

 

 

能夠在介紹中看到,該產品包含了兩個部分,其中「spring-amqp」是一個基本的抽象實現,而「spring-rabbit」是一個基於RabbitMQ的一個具體實現。併發

其實就是說,「spring-amqp」是全部符合消息隊列協議產品的基礎實現,而實現該基礎的產品有不少,「spring-rabbit」就是其中一種。mvc

2、spring-rabbit使用
首先咱們在Eclipse中建立一個maven項目:app

 

 

而後編輯POM文件,添加spring核心依賴、日誌相關依賴:框架

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.test.spring.rabbit</groupId>
<artifactId>spring_rabbit_test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<dependencies>
<dependency>
<groupId>com.rabbitmq</groupId>
<artifactId>amqp-client</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>

<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>1.4.0.RELEASE</version>
</dependency> 

<!-- spring核心依賴 -->
<dependency> 
<groupId>org.springframework</groupId> 
<artifactId>spring-core</artifactId> 
<version>4.2.5.RELEASE</version> 
</dependency>

<dependency> 
<groupId>org.springframework</groupId> 
<artifactId>spring-context</artifactId> 
<version>4.2.5.RELEASE</version> 
</dependency> 
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<version>3.0</version>
</configuration>
</plugin>
</plugins>
</build>
</project>

  


其中,spring-rabbit就是本次結合RabbitMQ的核心依賴jar,而amqp-client是rabbit通訊的基礎協議依賴。maven

而後咱們在maven工程的「src/main/resources」下建立日誌配置文件「logj4.properties」:

log4j.rootLogger=DEBUG,A1
log4j.logger.com.jack = DEBUG
log4j.logger.org.mybatis = DEBUG

log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n

  

下面是重點,在maven工程的「src/main/resources」下建立「rabbitmq-context,xml」來注入RabbitMQ須要的相關工廠類:
  
在該配置

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd">

<!-- 定義RabbitMQ的鏈接工廠 -->
<rabbit:connection-factory id="connectionFactory"
host="127.0.0.1" port="5672" username="jack" password="jack"
virtual-host="/jack" />

<!-- 定義Rabbit模板,指定鏈接工廠以及定義exchange -->
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" exchange="fanoutExchange" />
<!-- 若是須要定義路由key,則須要添加routing-key參數指定路由key,如:routing-key="foo.bar" -->

<!-- MQ的管理,包括隊列、交換器等 -->
<rabbit:admin connection-factory="connectionFactory" />

<!-- 定義隊列,自動聲明 -->
<rabbit:queue name="myQueue" auto-declare="true"/>

<!-- 定義交換器,自動聲明 -->
<rabbit:fanout-exchange name="fanoutExchange" auto-declare="true">
<rabbit:bindings>
<rabbit:binding queue="myQueue"/>
</rabbit:bindings>
</rabbit:fanout-exchange>
<!-- 若是交換機爲通配符類型,則須要在隊列中定義通配符的key(pattern),如:pattern="foo.*" -->

<!-- 隊列監聽 -->
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener ref="foo" method="listen" queue-names="myQueue" />
</rabbit:listener-container>

<bean id="foo" class="cn.jack.rabbitmq.spring.Foo" />

</beans>

  

文件中,首先定義了RabbitMQ的鏈接工廠:

<!-- 定義RabbitMQ的鏈接工廠 -->
<rabbit:connection-factory id="connectionFactory"
host="127.0.0.1" port="5672" username="jack" password="jack"
virtual-host="/jack" />
而該鏈接工廠作的事情,和以前咱們本身編寫的鏈接工廠作的事情是同樣的:
package cn.jack.rabbitmq.connection;
import java.io.IOException;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

public class ConnectionUtil {
public static Connection getConnection() throws IOException{
//定義鏈接工廠
ConnectionFactory factory = new ConnectionFactory();
//定義鏈接地址
factory.setHost("localHost");
//定義端口
factory.setPort(5672);
//設置帳號信息,用戶名、密碼、vhost
factory.setVirtualHost("/jack");
factory.setUsername("jack");
factory.setPassword("jack");
// 經過工廠獲取鏈接
Connection connection = factory.newConnection();
return connection;
}
}

  


都是定義一些列鏈接信息後,經過工廠獲取RabbitMQ的鏈接對象。

而後下面的配置是定義Rabbit模板,指定鏈接工廠以及定義exchange(交換機):

<!-- 定義Rabbit模板,指定鏈接工廠以及定義exchange -->
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory" exchange="fanoutExchange" />

  


該處作的事情,就是定義一個模板,指定其獲取鏈接的鏈接工廠,和其綁定的交換機。
若是是路由或通配符那種須要定義發送消息的路由key的交換機,則須要再添加一個「routing-key」參數來指定路由key:

<!-- 若是須要定義路由key,則須要添加routing-key參數指定路由key -->
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory"
exchange="fanoutExchange" routing-key="foo.bar" />

  


對於上面綁定的交換機,在下面有定義其詳細配置:

<!-- 定義交換器,自動聲明 -->
<rabbit:fanout-exchange name="fanoutExchange" auto-declare="true">
<rabbit:bindings>
<rabbit:binding queue="myQueue"/>
</rabbit:bindings>
</rabbit:fanout-exchange>

  


其中auto-declare是指,是否進行自動聲明,便是若是交換機不存在時,spring會幫助建立該交換機,若是交換機存在則忽略。在裏面的「rabbit:bindings」中配置的便是與該交換機綁定的隊列。
有三種交換機類型「fanout-exchange」、「direct-exchange」以及「topic-exchange」,分別是「非路由交換機」、「路由交換機」以及「通配符交換機」,具體區別在以前的總結中已經介紹,這裏再也不贅述。
上面的配置是「fanout-exchange」類型的交換機,若是須要其餘類型的,按照不一樣的前綴進行指定。下面是通配符交換機的配置方式:

<!-- 若是交換機爲通配符類型,則須要在隊列中定義通配符的key(pattern) -->
<rabbit:topic-exchange name="myExchange">
<rabbit:bindings>
<rabbit:binding queue="myQueue" pattern="foo.*" />
</rabbit:bindings>
</rabbit:topic-exchange>

  


首先將配置標籤訂義爲「topic-exchange」,而後裏面的隊列要指定相關的key鍵,用以接收符合該key的消息。

對於名爲「myQueue」隊列也在上面定義了,而且也配置了自動聲明:

<!-- 定義隊列,自動聲明 -->
<rabbit:queue name="myQueue" auto-declare="true"/>

  


在上面還有一個配置,是RabbitMQ的管理中心:

<!-- MQ的管理,包括隊列、交換器等 -->
<rabbit:admin connection-factory="connectionFactory" />

  


它的做用就是管理交換機和隊列的,對於交換機和路由器上面設置的「auto-declare」自動聲明,是由上面的MQ管理中心來作自動聲明的工做的。

上面所講解的配置,其實已經完成了一個生產者所作的事情。那麼最後就是配置消費者的相關設置,便是「隊列監聽」:

<!-- 隊列監聽 -->
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener ref="foo" method="listen" queue-names="myQueue" />
</rabbit:listener-container>

<bean id="foo" class="cn.jack.rabbitmq.spring.Foo" />

  


首先爲隊列監聽配置一個鏈接工廠,而後在其中配置消費者的依賴id、執行監聽的方法名以及接受消息的隊列名稱。

對於rabbit:listener中的ref中的對象id,在下面有一個bean的配置,會將foo對象加載到spring的bean容器中。

配置文件講解完畢,咱們基於該配置來建立一個生產者和消費者。
在「src/mian/java」下建立一個SpringMain類,在其中建立一個mian方法,編寫生產者的邏輯:

package cn.jack.rabbitmq.spring;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringMain {
public static void main(String[] args) throws Exception {
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext(
"classpath:rabbitmq-context.xml");
//Rabbit模板
RabbitTemplate template = ctx.getBean(RabbitTemplate.class);
//發送消息
template.convertAndSend("Hello,world!");
Thread.sleep(1000);//休眠1秒
ctx.close();//關閉容器
}
}

  


在該類中,首先使用ClassPathXmlApplicationContext獲取xml配置的對象ctx,而後經過getBean獲取「RabbitTemplate」類型的Rabbit模板,以後執行convertAndSend方法將消息發送至交換機或隊列,最後執行ctx的close關閉容器。

其實上面咱們業務層須要關注的就是獲取RabbitTemplate併發送消息,以前的ClassPathXmlApplicationContext獲取xml配置對象的操做在通常的企業工程中是不會這樣寫的,通常會進行包掃描和自動註解注入的方式獲取相關的bean,無需直接操做ClassPathXmlApplicationContext獲取xml配置對象:
消息發送類:

package com.training.rabbitmq.sender; 
import org.springframework.amqp.core.AmqpTemplate; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 

@Component 
public class DemoRabbitMqSender { 

@Autowired 
private AmqpTemplate rabbitTemplate; 

public void send(String content) { 
System.out.println("Sender : " + content); 
this.rabbitTemplate.convertAndSend("hello", content); 
} 

}

  


消息接收類

package com.training.rabbitmq.controller; 
import io.swagger.annotations.ApiOperation; 
import javax.servlet.http.HttpSession; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.ResponseBody; 
import org.springframework.web.bind.annotation.RestController; 
import com.training.core.dto.ResultDataDto; 
import com.training.rabbitmq.sender.DemoRabbitMqSender; 

@RestController 
@RequestMapping(value="/rabbitmq") 
public class DemoRabbitMqController { 

@Autowired 
private DemoRabbitMqSender demoRabbitMqSender; 

/** 
* 發送測試消息隊列 
*/ 
@ApiOperation(value="發送測試消息隊列", notes="addEntity") 
@RequestMapping(value = "/addRabbitMq", method = RequestMethod.GET) 
public @ResponseBody ResultDataDto addEntity(HttpSession httpSession) { 
demoRabbitMqSender.send("Hello,World!"); 
return ResultDataDto.addAddSuccess(); 
} 
}

  


上面的代碼僅供參考,不使用於本篇建立的樣例工程,由於這裏沒有集成Spring的其它環境(核心/web/mvc等),僅僅爲了方便演示rabbit的整合,因此直接使用了ClassPathXmlApplicationContext。

對於消費者,它的編寫就十分的簡單。以前配置文件中配置了一個foo的bean:

<bean id="foo" class="cn.jack.rabbitmq.spring.Foo" />

  


因此咱們下面在「src/mian/java」下建立cn.jack.rabbitmq.spring包下的Foo類:

package cn.jack.rabbitmq.spring;
public class Foo {
//具體執行業務的方法
public void listen(String foo){
System.out.println("消費者:"+foo);
}
}

  


代碼十分簡單,複雜的傳輸過程已經由spring經過配置文件的規則進行了處理。上面的listen方法便是在隊列監聽中配置的「method」參數:

<!-- 隊列監聽 -->
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener ref="foo" method="listen" queue-names="myQueue" />
</rabbit:listener-container>

  


下面咱們運行SpringMain類的main方法,能夠在控制檯看到以下信息:

 

 

而後到RabbitMQ的管理工具中查看隊列:

 

 

能夠看到建立了一個新的名爲「MyQueue」的隊列。
至此,Spring與RabbitMQ結合的小樣例工程編寫完畢。

後期將會編寫一個結合Web工程的RabbitMQ與Spring結合的實例,到時將使用包掃描和註解的方式注入Rabbit模板的實現。

轉載請註明出處:http://blog.csdn.net/acmman/article/details/79601121————————————————版權聲明:本文爲CSDN博主「光仔December」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處連接及本聲明。原文連接:https://blog.csdn.net/acmman/article/details/79601121

相關文章
相關標籤/搜索