一、代碼結構
使用Maven管理代碼,導入ActiveMQ的包
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-core</artifactId>
<version>5.7.0</version>
</dependency>
二、openwire協議通信
1、Producer:
package com.xuwei.activemq;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Sender {
private static final int SEND_NUMBER = 5;
public static void main(String[] args) {
// ConnectionFactory :連接工廠,JMS 用它創建連接
ConnectionFactory connectionFactory;
// Connection :JMS 客戶端到JMS Provider 的連接
Connection connection = null;
// Session: 一個發送或接收消息的線程
Session session;
// Destination :消息的目的地;消息發送給誰.
Destination destination;
// MessageProducer:消息發送者
MessageProducer producer;
// TextMessage message;
// 構造ConnectionFactory實例對象,此處採用ActiveMq的實現jar
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
// 構造從工廠得到連接對象
connection = connectionFactory.createConnection();
// 啓動
connection.start();
// 獲取操作連接
session = connection.createSession(Boolean.TRUE,
Session.AUTO_ACKNOWLEDGE);
// 獲取session注意參數值xingbo.xu-queue是一個服務器的queue,須在在ActiveMq的console配置
destination = session.createQueue("FirstQueue");
//destination = session.createTopic("FirstTopic");//主題
// 得到消息生成者【發送者】
producer = session.createProducer(destination);
// 設置不持久化,此處學習,實際根據項目決定
producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
// 構造消息,此處寫死,項目就是參數,或者方法獲取
sendMessage(session, producer);
session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
public static void sendMessage(Session session, MessageProducer producer)
throws Exception {
for (int i = 1; i <= SEND_NUMBER; i++) {
TextMessage message = session
.createTextMessage("ActiveMq 發送的消息" + i);
// 發送消息到目的地方
System.out.println("發送消息:" + "ActiveMq 發送的消息" + i);
producer.send(message);
}
}
}
2、Consumer:
package com.xuwei.activemq;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class Receiver {
public static void main(String[] args) {
// ConnectionFactory :連接工廠,JMS 用它創建連接
ConnectionFactory connectionFactory;
// Connection :JMS 客戶端到JMS Provider 的連接
Connection connection = null;
// Session: 一個發送或接收消息的線程
Session session;
// Destination :消息的目的地;消息發送給誰.
Destination destination;
// 消費者,消息接收者
MessageConsumer consumer;
connectionFactory = new ActiveMQConnectionFactory(
ActiveMQConnection.DEFAULT_USER,
ActiveMQConnection.DEFAULT_PASSWORD,
"tcp://localhost:61616");
try {
// 構造從工廠得到連接對象
connection = connectionFactory.createConnection();
// 啓動
connection.start();
// 獲取操作連接
session = connection.createSession(Boolean.FALSE,
Session.AUTO_ACKNOWLEDGE);
// 獲取session注意參數值xingbo.xu-queue是一個服務器的queue,須在在ActiveMq的console配置
destination = session.createQueue("FirstQueue");
consumer = session.createConsumer(destination);
/*
connection.setClilentID("client_001");
Topic topic = session.createTopic("FirstTopic");
consumer = session.createDurableSubscriber(topic, "client_001");//訂閱主題
*/
while (true) {
//設置接收者接收消息的時間,爲了便於測試,這裏誰定爲100s
TextMessage message = (TextMessage) consumer.receive(100000);
if (null != message) {
System.out.println("收到消息" + message.getText());
} else {
break;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != connection)
connection.close();
} catch (Throwable ignore) {
}
}
}
}
另外,消費者可以通過事件監聽的方式來處理消息,上面 while (true) { ... } 部分修改爲:
...
consumer.setMessageLisener(new MessageListener() {
@Override
public viod onMessage(Message message)
{
try{
TextMessage txtMessage = (TextMessage) message;
if(null != txtMessage) {
String msg = txtMessage.getText();
System.out.println(msg);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
...
三、與Spring整合
1、生產者
Spring配置:
<!-- 創建工廠連接 -->
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<!-- activeMQ消息目標 隊列 -->
<bean id="rantzDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="rantz.marketing.queue"></constructor-arg>
</bean>
<!-- activeMQ消息目標 主題-->
<!-- <bean id="rantzDestination" class="org.apache.activemq.command.ActiveMQTopic">-->
<!-- <constructor-arg index="0" value="rantz.marketing.queue"></constructor-arg>-->
<!-- </bean>-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
<bean id="marketingGateway" class="com.jms.service.RantzMarketingGatewayImpl">
<property name="jmsTemplate" ref="jmsTemplate" />
<property name="destination" ref="rantzDestination" />
</bean>
主程序:
public static void main(String[] args) {
/*開始加載spring配置文件*/
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
IRantzMarketingGateway rantzMarketingGateway= (RantzMarketingGatewayImpl) context.getBean("marketingGateway");
rantzMarketingGateway.sendMotoristInfo();
System.out.println("Start ...");
}
消息發送類:
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
public class RantzMarketingGatewayImpl implements IRantzMarketingGateway {
private JmsTemplate jmsTemplate;
private Destination destination;
public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public Destination getDestination() {
return destination;
}
public void setDestination(Destination destination) {
this.destination = destination;
}
public void sendMotoristInfo(){
jmsTemplate.send(
destination,
new MessageCreator(){
public Message createMessage(Session session) throws JMSException {
return session.createTextMessage("這是一個測試");
}
}
);
}
}
2、消費者
Spring配置:
<!-- 創建工廠連接 -->
<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<!-- activeMQ消息目標 隊列 -->
<bean id="rantzDestination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="rantz.marketing.queue"></constructor-arg>
</bean>
<!-- activeMQ消息目標 主題-->
<!-- <bean id="rantzDestination" class="org.apache.activemq.command.ActiveMQTopic">-->
<!-- <constructor-arg index="0" value="rantz.marketing.queue"></constructor-arg>-->
<!-- </bean>-->
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="connectionFactory" />
<property name="defaultDestination" ref="rantzDestination" />
</bean>
<bean id="marketingGateway" class="com.huateng.jms.service.MarketingReceiverGatewayImpl">
<property name="jmsTemplate" ref="jmsTemplate" />
</bean>
主程序:
public static void main(String[] args) {
/*開始加載spring配置文件*/
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
MarketingReceiverGatewayImpl rantzMarketingGateway= (MarketingReceiverGatewayImpl) context.getBean("marketingGateway");
System.out.println("Receive Start ...");
try {
rantzMarketingGateway.receiveMotorist();
} catch (Exception e) {
e.printStackTrace();
}
}
消息接收類:
import javax.jms.TextMessage;
import org.springframework.jms.core.JmsTemplate;
public class MarketingReceiverGatewayImpl {
private JmsTemplate jmsTemplate;
public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}
public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}
public MarketingReceiverGatewayImpl() {
}
public void receiveMotorist() throws Exception{
TextMessage message = (TextMessage)jmsTemplate.receive();
System.out.println("reviced msg is:" + message.getText());
}
}
四、Stomp協議通信
1、資源地址
1)Stomp協議實現:http://stomp.github.io/implementations.html
2)Stomp協議AS3實現:as3-storm
2、生產者(Java)
修改Openwire協議示例中的生產者代碼:
public static void sendMessage(Session session, MessageProducer producer)
throws Exception {
for (int i = 1; i <= SEND_NUMBER; i++) {
String msg = "ActiveMq 發送的消息" + i;
TextMessage message = session.createByteMessage();
message.writeUTF(msg);
System.out.println(msg);
producer.send(message);
}
}
3、消費者(Flex)
...
<mx:Script>
import flash.utils.ByteArray;
import org.codehaus.stomp.event.MessageEvent;
import org.codehaus.stomp.headers.ConnectHeaders;
private var destination:String = "/queue/FirstQueue"; //"/queue"打頭表示隊列;"/topic"打頭表示主題
private function init():void
{
var ch:ConnectHeaders = new ConnectHeaders();
ch.login= = "guest";
ch.passcode = "guest";
stomp.connect("localhost", 61613, ch);
stomp.subscribe(destination);
}
private function handleMessages(event:MessageEvent):void
{
var bytes:ByteArray = event.message.body;
var s:String = bytes.readUTF();
trace("收到消息" + s);
}
</mx:Script>
<stomp:Stomp id="stomp" message="handleMessages(event)"/>
...
五、測試
以(二)中示例程序測試。
1、P2P模式(Queue)
測試一:
A、 先運行Sender類,待運行完畢後,運行Receiver類
B、 在此過程中activemq數據庫的activemq_msgs表中沒有數據
C、 再次運行Receiver,消費不到任何信息
測試二:
A、 先運行Sender類
B、 重啓電腦
C、 運行Receiver類,無任何信息被消費
測試三:
A、 把Sender類中的producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);改爲producer.setDeliveryMode(DeliveryMode.PERSISTENT);
B、 先運行Sender類,待運行完畢後,運行Receiver類
C、 在此過程中activemq數據庫的activemq_msgs表中有數據生成,運行完Receiver類後,數據清除
測試四:
A、 把Sender類中的producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);改爲producer.setDeliveryMode(DeliveryMode.PERSISTENT);
B、 運行Sender類
C、 重啓電腦
D、 運行Receiver類,有消息被消費
結論:
通過以上測試,可以發現,在P2P類型中當DeliveryMode設置爲NON_PERSISTENCE時,消息被保存在內存中,而當DeliveryMode設置爲PERSISTENCE時,消息保存在broker的相應的文件或者數據庫中。而且P2P中消息一旦被Consumer消費就從broker中刪除。
2、Pub/Sub模式(Topic)
測試一:
A、先啓動Sender類
B、再啓動Receiver類
C、結果無任何記錄被訂閱
測試二:
A、先啓動Receiver類,讓Receiver在相關主題上進行訂閱
B、停止Receiver類,再啓動Sender類
C、待Sender類運行完成後,再啓動Receiver類
D、結果發現相應主題的信息被訂閱
Ø
參考:
http://www.cnblogs.com/xwdreamer/archive/2012/02/21/2360818.html
http://blog.csdn.net/xueyepiaoling/article/details/6321100
http://itindex.net/detail/44553-activemq