一、代码结构
使用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.youkuaiyun.com/xueyepiaoling/article/details/6321100
http://itindex.net/detail/44553-activemq