Spring-AMQP使用和簡單實例

之前寫過按照官方文檔學習使用RabbitMQ,瞭解了大概之後,我們可以開始嘗試在項目裏使用它。

1.前提準備

RabbitMQ,可以搭建在linux環境和windows環境。安裝比較簡單,這邊先不贅述了。以後補上。
我們要引入jar包,給出maven

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

版本自行選擇。
開一個項目,這裏是使用xml去配置。
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">

    <description>Spring公共配置</description>
    <!-- 掃描註解 -->
    <context:component-scan base-package="com.george"/>
    <context:annotation-config/>
    <!-- mq服務 生產者配置 -->
    <import resource="classpath:context/applicationContext-producer-mq.xml"/>
     <!-- mq服務 消費者配置 -->
    <import resource="classpath:context/applicationContext-consumer-mq.xml"/>
</beans>

準備一下properties文件,消費者和生產者都需要!
mq.properties

#參數
mq.host = 主機ip
mq.username = 用戶名
mq.password = 密碼
mq.port = 5672
mq.vhost = /
#消息確認
mq.publisher-confirms = true
#緩存數量,默認25
mq.channel-cache-size = 50

1.生產者

我們現在先安排生產者:
在業務代碼中,我們一般都期望這種調用能夠儘可能的簡便。所以最好的情況就是通過注入和設置參數我們可以直接發送消息。
applicationContext-producer-mq.xml

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
         http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 消息對象json轉換類 -->
    <bean id="jsonMessageConverter" class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" />

    <!-- 配置文件位置 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath*:mq.properties" ignore-resource-not-found="true"/>

    <!-- 連接工廠配置 -->
    <rabbit:connection-factory id="connectionFactory"
                                host="${mq.host}"
                                port="${mq.port}"
                                username="${mq.username}"
                                password="${mq.password}"
                                virtual-host="${mq.vhost}"
                                publisher-confirms="${mq.publisher-confirms}"
                                channel-cache-size="${mq.channel-cache-size}"/>

    <rabbit:admin connection-factory="connectionFactory"/>

    <!--定義消息隊列-->
    <!-- durable:持久化,是否持久化日誌,恢復消息隊列 -->
    <!-- auto-delete:當所有消費者客戶端斷開連接後,是否自動刪除隊列 -->
    <!-- exclusive:是否是創建者的私有隊列,斷開後自動刪除 -->
    <!-- auto-declare:是否自動聲明 -->
    <rabbit:queue name="queue1" durable="true" auto-delete="false" exclusive="false" auto-declare="true"/>
    <rabbit:queue name="queue2"/>

    <!-- 定義交換機 -->
    <rabbit:direct-exchange id="directExchange" name="directExchange" durable="true" auto-delete="false">
        <!-- 綁定隊列 -->
        <rabbit:bindings>
            <rabbit:binding queue="queue1" key="queue1"/>
            <!--<rabbit:binding queue="queue2" key="queue2"/>-->
        </rabbit:bindings>
    </rabbit:direct-exchange>

    <!-- rabbit模板聲明 -->
    <rabbit:template id="rabbitTemplateDirect"
                     connection-factory="connectionFactory"
                     exchange="directExchange"
                     routing-key="queue1"/>

    <!--<rabbit:template id="rabbitTemplateTopic"-->
                     <!--connection-factory="connectionFactory"-->
                     <!--exchange="topicExchange"-->
                     <!--routing-key="queue2" />-->


    <!-- 監聽處理 -->
    <bean id="queueListener" class="com.george.QueueListener"/>

    <!-- 監聽器 -->
    <rabbit:listener-container connection-factory="connectionFactory" acknowledge="auto">
        <rabbit:listener ref="queueListener" method="execute" queue-names="queue1"/>
    </rabbit:listener-container>

</beans>

這裏單獨解釋一下template,這個就是在代碼裏要自動注入的了,所以我們需要現在這裏給他配置好,可以設置其id,交換機和rouing-key。這邊選用常見又容易講的direct模式。當然其他的可以配置, 只要id不重複就可以。其他的寫了註釋就不多說啦。

現在我去創建了service和它的實現類

@Service("messageProducer")
public class MessageProducerImpl implements MessageProducer {

    @Resource(name = "rabbitTemplateDirect")
    private AmqpTemplate rabbitTemplateDirect;

    @Override
    public void sendDataToQueue(String exchangeName, String routingKey, Object object) throws Exception {
        rabbitTemplateDirect.convertAndSend(routingKey, object);
    }
}

在注入的時候,@Resource的name屬性就對應着xml中配置的template的id,這樣我們就可以選擇我們想要的。

請注意!!!

最好強行拋出異常,等使用的時候進行try/catch,避免因爲rabbitmq無法啓動或者其他問題,導致業務流程無法繼續進行!!!!

 rabbitTemplateDirect.convertAndSend(routingKey, object);

是提供給我們的方法,直接發送消息到指定的routing路徑下。
測試類:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:context/applicationContext.xml")
public class MqProducerTest {

    @Resource
    private MessageProducer messageProducer;

    @Test
    public void send() {
        List<String> list = new ArrayList<>();
        list.add("tom");
        list.add("jack");
        list.add("mark");
        String toJson = new Gson().toJson(list);
       
         try {
            messageProducer.sendDataToQueue("directExchange","queue1", toJson);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

我們發送一個list,轉成json發送,執行之後我們就可以去webUI那邊看一下消息是不是發送了。順着Exchange或者Queue都能找到。

2.消費者

想比較與生產者,消費者簡單一些,但是要注意參數!後面會說明。

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
         http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 消息對象json轉換類 -->
    <bean id="jsonMessageConverter" class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" />

    <!-- 配置文件位置 -->
    <context:property-placeholder ignore-unresolvable="true" location="classpath*:mq.properties" ignore-resource-not-found="true"/>

    <!-- 連接工廠配置 -->
    <rabbit:connection-factory id="connectionFactory"
                                host="${mq.host}"
                                port="${mq.port}"
                                username="${mq.username}"
                                password="${mq.password}"
                                virtual-host="${mq.vhost}"
                                publisher-confirms="${mq.publisher-confirms}"
                                channel-cache-size="${mq.channel-cache-size}"/>

    <rabbit:admin connection-factory="connectionFactory"/>

    <rabbit:queue name="queue1" durable="true" auto-declare="true"/>

    <!-- 監聽器 -->
    <rabbit:listener-container connection-factory="connectionFactory" acknowledge="auto">
        <rabbit:listener ref="queueListener" method="execute" queue-names="queue1"/>
    </rabbit:listener-container>

    <!-- 監聽處理 -->
    <bean id="queueListener" class="com.george.QueueListener"/>

</beans>

主要看下面,監聽器和監聽處理,這邊可以不繼承提供的接口,我們自己指定接受消息的方法。先看監聽處理,在com.george路徑下創建一個QueueListener類,爲了測試,這個類也是很簡單:

public class QueueListener {
    public void execute(String message) throws Exception {
        String json = new Gson().toJson(message);
        System.out.println(json);
    }
}

請注意!!!

剛纔說的參數,這裏設置的方法的參數一定要和發送者返回值相同,所以推薦json格式的string,因爲如果不一致,
將會無法接收到消息!

打印一下,看看效果。
我們寫一個消費者的應用
RabbitApp.java

public class RabbitApp {

    private static final Logger logger = LoggerFactory.getLogger(RabbitApp.class);

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("classpath:context/applicationContext-consumer-mq.xml");
        context.start();
        System.out.println("rabbit MQ Consumer start");
        try {
            System.in.read();	// 按任意鍵退出
        } catch (IOException e) {
            logger.error(e.getMessage());
        }
    }
}

啓動main方法,如果我們獲取到了消息,證明成功了。
結果
上面是執行消費者成功,下面是獲取到的消息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章