使用 ActiveMQ 示例

企業中各項目中相互協作的時候可能用得到消息通知機制。比如有東西更新了,可以通知做索引。

在 Java 裏有 JMS 的多個實現。其中 apache 下的 ActiveMQ 就是不錯的選擇。還有一個比較熱的是 RabbitMQ (是 erlang 語言實現的)。這裏示例下使用 ActiveMQ

用 ActiveMQ 最好還是瞭解下 JMS

JMS 公共 點對點域 發佈/訂閱域
ConnectionFactory QueueConnectionFactory TopicConnectionFactory
Connection QueueConnection TopicConnection
Destination Queue Topic
Session QueueSession TopicSession
MessageProducer QueueSender TopicPublisher
MessageConsumer QueueReceiver TopicSubscriber

JMS 定義了兩種方式:Quere(點對點);Topic(發佈/訂閱)。

ConnectionFactory 是連接工廠,負責創建Connection。

Connection 負責創建 Session。

Session 創建 MessageProducer(用來發消息) 和 MessageConsumer(用來接收消息)。

Destination 是消息的目的地。

詳細的可以網上找些 JMS 規範(有中文版)。

下載 apache-activemq-5.3.0。http://activemq.apache.org/download.html,解壓,然後雙擊 bin/activemq.bat。運行後,可以在 http://localhost:8161/admin 觀察。也有 demo, http://localhost:8161/demo。把 activemq-all-5.3.0.jar 加入 classpath。

Jms 發送 代碼:

public static void main(String[] args) throws Exception {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory();

Connection connection = connectionFactory.createConnection();
connection.start();

Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("my-queue");

MessageProducer producer = session.createProducer(destination);
for(int i=0; i<3; i++) {
MapMessage message = session.createMapMessage();
message.setLong("count", new Date().getTime());
Thread.sleep(1000);
//通過消息生產者發出消息
producer.send(message);
}
session.commit();
session.close();
connection.close();
}
Jms 接收代碼:

public static void main(String[] args) throws Exception {
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory();

Connection connection = connectionFactory.createConnection();
connection.start();

final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
Destination destination = session.createQueue("my-queue");

MessageConsumer consumer = session.createConsumer(destination);
/*//listener 方式
consumer.setMessageListener(new MessageListener() {

public void onMessage(Message msg) {
MapMessage message = (MapMessage) msg;
//TODO something....
System.out.println("收到消息:" + new Date(message.getLong("count")));
session.commit();
}

});
Thread.sleep(30000);
*/
int i=0;
while(i<3) {
i++;
MapMessage message = (MapMessage) consumer.receive();
session.commit();

//TODO something....
System.out.println("收到消息:" + new Date(message.getLong("count")));
}

session.close();
connection.close();
}
啓動 JmsReceiver 和 JmsSender 可以在看輸出三條時間信息。當然 Jms 還指定有其它格式的數據,如 TextMessage

結合 Spring 的 JmsTemplate 方便用:

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

<!-- 在非 web / ejb 容器中使用 pool 時,要手動 stop,spring 不會爲你執行 destroy-method 的方法
<bean id="jmsFactory" class="org.apache.activemq.pool.PooledConnectionFactory" destroy-method="stop">
<property name="connectionFactory">
<bean class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
</property>
</bean>
-->
<bean id="jmsFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="jmsFactory" />
<property name="defaultDestination" ref="destination" />
<property name="messageConverter">
<bean class="org.springframework.jms.support.converter.SimpleMessageConverter" />
</property>
</bean>

<bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
<constructor-arg index="0" value="my-queue" />
</bean>

</beans>
sender:

public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:app*.xml");

JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate");

jmsTemplate.send(new MessageCreator() {

public Message createMessage(Session session) throws JMSException {
MapMessage mm = session.createMapMessage();
mm.setLong("count", new Date().getTime());
return mm;
}

});
}
receiver:

public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext("classpath:app*.xml");

JmsTemplate jmsTemplate = (JmsTemplate) ctx.getBean("jmsTemplate");
while(true) {
Map<String, Object> mm = (Map<String, Object>) jmsTemplate.receiveAndConvert();
System.out.println("收到消息:" + new Date((Long)mm.get("count")));
}
}
注意:直接用 Jms 接口時接收了消息後要提交一下,否則下次啓動接收者時還可以收到舊數據。有了 JmsTemplate 就不用自己提交 session.commit() 了。如果使用了 PooledConnectionFactory 要把 apache-activemq-5.3.0\lib\optional\activemq-pool-5.3.0.jar 加到 classpath

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