1. 程式人生 > >activeMQ例項在專案中的運用【專案實戰系列】

activeMQ例項在專案中的運用【專案實戰系列】

1.下載ActiveMQ

去官方網站下載:http://activemq.apache.org/

2.執行ActiveMQ

解壓縮apache-activemq-5.14.0-bin.zip,然後雙擊apache-activemq-5.14.0\bin\activemq.bat執行ActiveMQ程式。

啟動ActiveMQ以後,登陸:http://localhost:8161/admin/ ,賬戶和密碼都是admin,然後可以自己新增一個Queue,這次專案

們通過程式碼建立一個Queue.

好了,activeMQ就已經完成了部署,那麼怎麼把他運用到我們專案中呢,下面我就給大家介紹一下。

首先來看下我這個專案的整個目錄結構,總共分為3
個子專案,domain專案用於存放公共的實體類和工具類,打包成jar包供

其他2個包使用。Service專案則是activeMQ的提供者或者說是生產者,這裡主要是配置activeMQ的生成方式和建立Queue

那麼剩下來的client專案當然就是MQ的使用者或者說是消費者了,那邊產生訊息,這邊消費訊息。那我們來看看具體的程式碼

吧。

首先介紹domain的專案,這個專案裡面主要定義了三種實體類,User.java Client.java News.java 只是用於測試而已,

那就隨便看其中一個就好了,User.java

package com.lwl.activemq.domain;

import java.io.Serializable;
/**
 * 使用者測試類
 * @author Administrator
 *
 */
public class User implements Serializable{

	private static final long serialVersionUID = 1L;

	private long id;
	
	private String username;
	
	private String password;
	
	private String sex;
	
	private int age;

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", password="
				+ password + ", sex=" + sex + ", age=" + age + "]";
	}
}


domain專案新增好這3個實體類,就把這個專案通過maven打包成jar供其他2個專案使用即可。

那接下來我們來看下service專案的程式碼結構吧

首先我們來看一下最主要的MQ的配置檔案:

<?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:jms="http://www.springframework.org/schema/jms"
	xsi:schemaLocation="http://www.springframework.org/schema/beans  
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
     http://www.springframework.org/schema/context  
     http://www.springframework.org/schema/context/spring-context-3.0.xsd  
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
    http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd">

	<!-- 這裡暴露內部統一使用的MQ地址 -->
	<bean id="internalTargetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://localhost:61616" />
	</bean>
	<bean id="internalConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
		destroy-method="stop">
		<property name="connectionFactory" ref="internalTargetConnectionFactory" />
		<property name="maxConnections" value="20" />
	</bean>
	<!-- Spring提供的JMS工具類,它可以進行訊息傳送、接收等 -->
	<bean id="internalJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="internalConnectionFactory" />
	</bean>

	<!-- 推送給使用者資訊  建立一個Queue-->
	<bean id="userServiceQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg>
			<value>user.service.queue</value>
		</constructor-arg>
	</bean>
	<!-- 推送給新聞資訊   建立一個Queue-->
	<bean id="newsServiceQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg>
			<value>news.service.queue</value>
		</constructor-arg>
	</bean>
	<!-- 推送給客戶資訊   建立一個Queue-->
	<bean id="clientServiceQueue" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg>
			<value>client.service.queue</value>
		</constructor-arg>
	</bean>

	 
</beans>

那我們看下怎麼運用定義的這個配置檔案呢?

首先我們定義一個通用的推送介面PushService.java

package com.lwl.activemq.service;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 推送的介面
 * @author Administrator
 * @create 2016-8-10 下午3:41:03
 * @version 1.0
 */
public interface PushService {

	public final ExecutorService pushExecutor = Executors.newFixedThreadPool(10);
	
	public void push(Object info);
	
}


然後又實現了3中不同的推送內容:ClientPushServiceImpl.java  NewsPushServiceImpl.java  UserPushServiceImpl.java

就拿其中的一個來舉例,其他2個模式是一樣的

package com.lwl.activemq.service.impl;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

import com.alibaba.fastjson.JSON;
import com.lwl.activemq.domain.User;
import com.lwl.activemq.service.PushService;


@Service("userPushService")
public class UserPushServiceImpl implements PushService {

	
	@Autowired
	private JmsTemplate jmsTemplate;
	
	/**
	 * 這裡是根據MQ配置檔案定義的queue來注入的,也就是這裡將會把不同的內容推送到不同的queue中
	 */
	@Autowired
	@Qualifier("userServiceQueue")
	private Destination destination;
	
	@Override
	public void push(final Object info) {
		pushExecutor.execute(new Runnable() {
			@Override
			public void run() {
				jmsTemplate.send(destination, new MessageCreator() {
					public Message createMessage(Session session) throws JMSException {
						 User p = (User) info;
						return session.createTextMessage(JSON.toJSONString(p));
					}
				});
			}			
		});
	}

}


介面也已經實現好了,剩下的就是看我們怎麼呼叫它了,那我們看看控制器吧:

package com.lwl.activemq.controller;

import javax.annotation.Resource;

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.lwl.activemq.domain.Client;
import com.lwl.activemq.domain.News;
import com.lwl.activemq.domain.User;
import com.lwl.activemq.result.ResultRespone;
import com.lwl.activemq.service.PushService;

@Controller
@RequestMapping("/push")
public class PushController {

	@Resource(name="userPushService")
	private PushService userPushService;
	
	@Resource(name="newsPushService")
	private PushService newsPushService;
	
	@Resource(name="clientPushService")
	private PushService clientPushService;
	
	/**
	 * 使用者推送
	 * @param info
	 * @return
	 * @author Administrator
	 * @create 2016-8-10 下午4:22:28
	 */
	@RequestMapping(value="/user",method=RequestMethod.POST)
	@ResponseBody
	public ResultRespone userPush(User info){
		ResultRespone respone = new ResultRespone();
		try {
			userPushService.push(info);
			respone.setData(info);
		} catch (Exception e) {
			e.printStackTrace();
			respone = new ResultRespone(false, e.getMessage());
		}
		return respone;
	}
	
	/**
	 * 新聞推送
	 * @param info
	 * @return
	 * @author Administrator
	 * @create 2016-8-10 下午4:22:38
	 */
	@RequestMapping(value="/news",method=RequestMethod.POST)
	@ResponseBody
	public ResultRespone newsPush(News info){
		ResultRespone respone = new ResultRespone();
		try {
			newsPushService.push(info);
			respone.setData(info);
		} catch (Exception e) {
			e.printStackTrace();
			respone = new ResultRespone(false, e.getMessage());
		}
		return respone;
	}
	/**
	 * 客戶推送
	 * @param info
	 * @return
	 * @author Administrator
	 * @create 2016-8-10 下午4:22:48
	 */
	@RequestMapping(value="/client",method=RequestMethod.POST)
	@ResponseBody
	public ResultRespone clientPush(Client info){
		ResultRespone respone = new ResultRespone();
		try {
			clientPushService.push(info);
			respone.setData(info);
		} catch (Exception e) {
			e.printStackTrace();
			respone = new ResultRespone(false, e.getMessage());
		}
		return respone;
	}
}

控制器也寫好了,剩下的就是前段頁面的呼叫了,那就快來看看吧index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
          <script type="text/javascript" src="resources/jquery-1.9.1.js"></script>
     </head>   
<body>
<br/><br/><br/>
使用者姓名:<input type="text" id="username" />
使用者密碼:<input type="text" id="password" />
使用者性別:<input type="text" id="sex" />
 <input type="button" value="推送使用者資訊" id="pushUser" /> 
 
<br/><br/><br/>
新聞標題:<input type="text" id="title" />
新聞內容:<input type="text" id="content" />
新聞路徑:<input type="text" id="url" />
新聞作者:<input type="text" id="author" />
 <input type="button" value="推送新聞資訊" id="pushNews" /> 


<br/><br/><br/>
客戶姓名:<input type="text" id="name" />
客戶地址:<input type="text" id="address" />
客戶手機:<input type="text" id="mobile" />
 <input type="button" value="推送客戶資訊" id="pushClient" /> 




<script type="text/javascript">
	$("#pushUser").click(function(){
		var data = {
				username : $("#username").val(),
				password : $("#password").val(),
				sex 	 : $("#sex").val()
		};
		ajaxDo("/activemq-service/push/user",data);
	});
	$("#pushNews").click(function(){
		var data = {
				title	 : $("#title").val(),
				content  : $("#content").val(),
				author 	 : $("#author").val(),
				url 	 : $("#url").val()
		};
		ajaxDo("/activemq-service/push/news",data);
	});
	$("#pushClient").click(function(){
		var data = {
				name	 : $("#name").val(),
				address  : $("#address").val(),
				mobile 	 : $("#mobile").val()
		};
		ajaxDo("/activemq-service/push/client",data);
	});
	
function ajaxDo(url,data){
	 $.ajax({
	        url:url ,
	        type: "post",
	        dataType: "json",
	        data: data,
	        success:function(result){
	           if(result.success){
	        	   var obj = JSON.stringify(result.data);
	        	   alert(obj);
	           }else{
	        	   alert(result.msg);
	           }
	        }
	    });
}	

</script>

</body>
</html>


現在程式碼都已經完成了,那就可以啟動專案了,啟動專案之前首先要啟動activeMQ,然後再啟動activemq-service專案,

開啟瀏覽器我們就可以模擬推送內容了:

此時在重新整理我們的MQ頁面你就會發現自動建立好了Queue,而且在User那個裡面會有1個訊息未被消費掉:


傳送端的程式碼就這樣已經完成了,明天將會繼續把接收端的程式碼寫出來,並且通過websocket推送到前端顯示出來