1. 程式人生 > >springmvc+spring+maven+ActiveMq之:點對點模式

springmvc+spring+maven+ActiveMq之:點對點模式

訊息服務:一箇中間件,用於解決兩個活多個程式之間的耦合,底層由Java 實現。
優勢:非同步、可靠
訊息模型:點對點,
JMS中的物件
需要安裝apache-activemq,下載安裝之後到暗轉目錄下的bin,找到activemq.bat雙擊執行。瀏覽器:http://localhost:8161/admin/ 使用者名稱和密碼都為admin,保持執行狀態
由於我自己的專案是搭建好的,所以直接有了springmvc+spring+maven所以我要做的就是把ActiveMq新增上去;
第一步jar:
這裡寫圖片描述
完整的pom.xml

這裡寫程式碼片
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>activemq</groupId> <artifactId>com.activemq</artifactId> <packaging
>
war</packaging> <version>0.0.1-SNAPSHOT</version> <name>activemq</name> <url>http://maven.apache.org</url> <properties> <springframework>4.2.6.RELEASE</springframework> </properties> <dependencies> <dependency
>
<groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springframework}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springframework}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>4.2.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jms</artifactId> <version>${springframework}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.2.6.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.2.6.RELEASE</version> </dependency> <dependency> <groupId>org.apache.xbean</groupId> <artifactId>xbean-spring</artifactId> <version>4.2</version> </dependency> <!-- activemq --> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-core</artifactId> <version>5.7.0</version> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-pool</artifactId> <version>5.12.1</version> </dependency> <!--alibabajson轉換jar --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.1.34</version> </dependency> <!-- 所有的Java日誌實現提供一個統一的介面jar --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-web</artifactId> <version>2.0.1</version> <scope>runtime</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-1.2-api</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.5.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.2.6.RELEASE</version> </dependency> <dependency> <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>commons-pool</groupId> <artifactId>commons-pool</artifactId> <version>1.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.18</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.7</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>3.0-alpha-1</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.6</version> <configuration> <warSourceDirectory>Web</warSourceDirectory> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> <finalName>com.activemq</finalName> </build> </project>

因為有很多別的東西所以這裡看起來東西比較多。
第二步:ActiveMq配置,
applicationContext-ActiveMQ.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"
    xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:amq="http://activemq.apache.org/schema/core" xmlns:jms="http://www.springframework.org/schema/jms"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd  
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.1.xsd  
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-4.1.xsd
        http://www.springframework.org/schema/jms
        http://www.springframework.org/schema/jms/spring-jms-4.1.xsd
        http://activemq.apache.org/schema/core
        http://activemq.apache.org/schema/core/activemq-core-5.7.0.xsd ">
    <mvc:annotation-driven />
    <!-- 對包中的所有類進行掃描,以完成Bean建立和自動依賴注入的功能 需要更改 -->
    <context:component-scan base-package="com.java.spring" />
    <!-- activemq連線池 -->
    <amq:connectionFactory id="amqConnectionFactory" brokerURL="tcp://localhost:61616" userName="admin" password="admin" />
    <!-- 配置JMS連線工廠 -->
    <bean id="connectionFactory"
        class="org.springframework.jms.connection.CachingConnectionFactory">
        <constructor-arg ref="amqConnectionFactory" />
        <property name="sessionCacheSize" value="100" />
    </bean>
    <!-- 定義訊息佇列(Queue) -->
    <bean id="demoQueueDestination" class="org.apache.activemq.command.ActiveMQQueue">
        <!-- 設定訊息佇列的名字 -->
        <constructor-arg>
            <value>Jaycekon</value>
        </constructor-arg>
    </bean>
    <!-- 配置JMS模板(Queue),Spring提供的JMS工具類,它傳送、接收訊息。 -->
    <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="defaultDestination" ref="demoQueueDestination" />
        <property name="receiveTimeout" value="10000" />
        <!-- true是topic,false是queue,預設是false,此處顯示寫出false -->
        <property name="pubSubDomain" value="false" />
    </bean>
    <!-- 配置訊息佇列監聽者(Queue) -->
    <bean id="queueMessageListener" class="com.java.spring.util.listener.QueueMessageListener" />
    <!-- 顯示注入訊息監聽容器(Queue),配置連線工廠,監聽的目標是demoQueueDestination,監聽器是上面定義的監聽器 -->
    <bean id="queueListenerContainer"
        class="org.springframework.jms.listener.DefaultMessageListenerContainer">
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="destination" ref="demoQueueDestination" />
        <property name="messageListener" ref="queueMessageListener" />
    </bean>

</beans>

這裡寫圖片描述
紅色部分為重點,主要為載入ActiveMq所用到標籤庫,一定要注意和pom.xml中版本相同
這裡寫圖片描述
這個部分程式碼可以先註釋(這是訊息監聽,初學者第一步一般都是手動獲取訊息所以用不到監聽獲取)
第三步:建立生產者(Producer)和消費者(Consumer);這裡我把生產者和消費都放在了一個介面實現類中
介面分別為:

package com.java.spring.service;

import javax.jms.Destination;

import org.springframework.stereotype.Service;

/**
* @author 作者:zhaofq
* @version 建立時間:2017年3月28日 上午10:19:15
* 類說明
*/
@Service
public interface ProducerService {

    public void sendMessage(Destination destination,final String msg);

     public void sendMessage(final String msg);

}
package com.java.spring.service;

import javax.jms.Destination;
import javax.jms.TextMessage;

/**
* @author 作者:zhaofq
* @version 建立時間:2017年3月28日 上午10:29:24
* 類說明
*/
public interface ConsumerService {


     public TextMessage receive();
}
package com.java.spring.serviceImpl;

import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.apache.log4j.Logger;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.stereotype.Service;

import com.java.spring.service.ProducerService;

/**
* @author 作者:zhaofq
* @version 建立時間:2017年3月28日 上午10:19:15
* 類說明
*/
@Service
public class ProducerServiceImpl implements ProducerService{
    private static Logger loger = Logger.getLogger(ProducerServiceImpl.class.getName());

    //指定訊息目的地的傳送方法
    @Resource(name="jmsTemplate")
    private JmsTemplate jmsTemplate;
    public void sendMessage(Destination destination,final String msg){
        System.out.println(Thread.currentThread().getName()+" 向佇列"+destination.toString()+"傳送訊息---------------------->"+msg);
        loger.info(Thread.currentThread().getName()+" 向佇列"+destination.toString()+"傳送訊息---------------------->"+msg);
        jmsTemplate.send(destination,new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(msg);
            }
        });
    }

    //預設訊息目的地的方法
    public void sendMessage(final String msg){
        Destination destination = jmsTemplate.getDefaultDestination();
        System.out.println(Thread.currentThread().getName()+" 向佇列"+destination+"傳送訊息---------------------->"+msg);
        loger.info(Thread.currentThread().getName()+" 向佇列"+destination+"傳送訊息---------------------->"+msg);
        jmsTemplate.send(new MessageCreator() {
            public Message createMessage(Session session) throws JMSException {
                return session.createTextMessage(msg);
            }
        });
     }
}
package com.java.spring.serviceImpl;

import javax.annotation.Resource;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.TextMessage;

import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Service;

import com.java.spring.service.ConsumerService;

/**
* @author 作者:zhaofq
* @version 建立時間:2017年3月28日 上午10:29:24
* 類說明
*/
@Service
public class ConsumerServiceImpl implements ConsumerService{
    //訊息目的地
    @Resource(name = "demoQueueDestination")
    Destination destination;

    @Resource(name="jmsTemplate")
    JmsTemplate jmsTemplate;

    public TextMessage receive(){
        TextMessage textMessage = (TextMessage) jmsTemplate.receive(destination);
        try{
            System.out.println("從佇列" + destination+ "收到了訊息:\t"
                    + textMessage.getText().toString());
        } catch (JMSException e) {
            e.printStackTrace();
        }
        return textMessage;
    }
}

由於我的專案已經是從瀏覽器訪問的,ssm專案,所以我直接用controller來呼叫介面方法實現訊息傳送和接收controller的內容為

package com.java.spring.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.java.spring.service.ConsumerService;
import com.java.spring.service.ProducerService;

/**
* @author 作者:zhaofq
* @version 建立時間:2017年3月28日 上午10:51:48
* 類說明
*/
@Controller
public class MessageController {



    @Autowired(required=false)
    ProducerService producerService;

    @Autowired(required=false)
    ConsumerService consumerService;


    @RequestMapping(value="/sendMessage",method=RequestMethod.GET)
    public @ResponseBody void send(String msg) {
        msg="helloActiveMq";
        producerService.sendMessage(msg);
    }

    @RequestMapping(value="/receiveMessage",method=RequestMethod.GET)
    public @ResponseBody void receive() {
        consumerService.receive();

    }

}

啟動tomcat測試沒問題:分別訪問/sendMessage和/receiveMessage
列印結果是:
傳送列印:
這裡寫圖片描述
接收列印:
這裡寫圖片描述
記得要是沒有註釋監聽那段程式碼的時候手動訪問是接收不到的,所以監聽和手動不能同時進行,因為監聽只要消費了就在佇列中麼有了.
下面看下通過監聽收到的訊息:監聽需要自己實現監聽類MessageListener

package com.java.spring.util.listener;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.springframework.jms.listener.adapter.MessageListenerAdapter;

/**
* @author 作者:zhaofq
* @version 建立時間:2017年3月28日 下午1:35:43
* 類說明
*/
public class QueueMessageListener implements MessageListener {
    public void onMessage(Message message) {
        TextMessage tm = (TextMessage) message;
        try {
            System.out.println("QueueMessageListener監聽到了文字訊息:\t"+ tm.getText());
            //do something ...
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
}

可以在監聽訊息收到之後做一些業務實現,測試方法,把applicationContext-ActiveMQ.xml中註釋的監聽部分配置開啟執行專案,訪問傳送訊息方法:
這裡寫圖片描述
程式碼可以github下載:
https://github.com/zhaofq/activemq.git
下一篇說釋出/訂閱模式