activeMQ

原文出处:http://blog.chenlb.com/2010/01/activemq-hello.html

<!-- google_ad_section_start -->

企业中各项目中相互协作的时候可能用得到消息通知机制。比如有东西更新了,可以通知做索引。

在 Java 里有 JMS 的多个实现。其中 apache 下的 ActiveMQ 就是不错的选择。还有一个比较热的是 RabbitMQ (是 erlang 语言实现的)。这里示例下使用 ActiveMQ

用 ActiveMQ 最好还是了解下 JMS

JMS 公共点对点域发布/订阅域
ConnectionFactoryQueueConnectionFactoryTopicConnectionFactory
ConnectionQueueConnectionTopicConnection
DestinationQueueTopic
SessionQueueSessionTopicSession
MessageProducerQueueSenderTopicPublisher
MessageConsumerQueueReceiverTopicSubscriber

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 发送 代码:

  1. publicstaticvoidmain(String[]args)throwsException{
  2. ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory();
  3. Connectionconnection=connectionFactory.createConnection();
  4. connection.start();
  5. Sessionsession=connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);
  6. Destinationdestination=session.createQueue("my-queue");
  7. MessageProducerproducer=session.createProducer(destination);
  8. for(inti=0;i<3;i++){
  9. MapMessagemessage=session.createMapMessage();
  10. message.setLong("count",newDate().getTime());
  11. Thread.sleep(1000);
  12. //通过消息生产者发出消息
  13. producer.send(message);
  14. }
  15. session.commit();
  16. session.close();
  17. connection.close();
  18. }
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 接收代码:

  1. publicstaticvoidmain(String[]args)throwsException{
  2. ConnectionFactoryconnectionFactory=newActiveMQConnectionFactory();
  3. Connectionconnection=connectionFactory.createConnection();
  4. connection.start();
  5. finalSessionsession=connection.createSession(Boolean.TRUE,Session.AUTO_ACKNOWLEDGE);
  6. Destinationdestination=session.createQueue("my-queue");
  7. MessageConsumerconsumer=session.createConsumer(destination);
  8. /*//listener方式
  9. consumer.setMessageListener(newMessageListener(){
  10. publicvoidonMessage(Messagemsg){
  11. MapMessagemessage=(MapMessage)msg;
  12. //TODOsomething....
  13. System.out.println("收到消息:"+newDate(message.getLong("count")));
  14. session.commit();
  15. }
  16. });
  17. Thread.sleep(30000);
  18. */
  19. inti=0;
  20. while(i<3){
  21. i++;
  22. MapMessagemessage=(MapMessage)consumer.receive();
  23. session.commit();
  24. //TODOsomething....
  25. System.out.println("收到消息:"+newDate(message.getLong("count")));
  26. }
  27. session.close();
  28. connection.close();
  29. }
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:

  1. <?xmlversion="1.0"encoding="UTF-8"?>
  2. <beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
  4. <!--在非web/ejb容器中使用pool时,要手动stop,spring不会为你执行destroy-method的方法
  5. <beanid="jmsFactory"class="org.apache.activemq.pool.PooledConnectionFactory"destroy-method="stop">
  6. <propertyname="connectionFactory">
  7. <beanclass="org.apache.activemq.ActiveMQConnectionFactory">
  8. <propertyname="brokerURL"value="tcp://localhost:61616"/>
  9. </bean>
  10. </property>
  11. </bean>
  12. -->
  13. <beanid="jmsFactory"class="org.apache.activemq.ActiveMQConnectionFactory">
  14. <propertyname="brokerURL"value="tcp://localhost:61616"/>
  15. </bean>
  16. <beanid="jmsTemplate"class="org.springframework.jms.core.JmsTemplate">
  17. <propertyname="connectionFactory"ref="jmsFactory"/>
  18. <propertyname="defaultDestination"ref="destination"/>
  19. <propertyname="messageConverter">
  20. <beanclass="org.springframework.jms.support.converter.SimpleMessageConverter"/>
  21. </property>
  22. </bean>
  23. <beanid="destination"class="org.apache.activemq.command.ActiveMQQueue">
  24. <constructor-argindex="0"value="my-queue"/>
  25. </bean>
  26. </beans>
<?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:

  1. publicstaticvoidmain(String[]args){
  2. ApplicationContextctx=newFileSystemXmlApplicationContext("classpath:app*.xml");
  3. JmsTemplatejmsTemplate=(JmsTemplate)ctx.getBean("jmsTemplate");
  4. jmsTemplate.send(newMessageCreator(){
  5. publicMessagecreateMessage(Sessionsession)throwsJMSException{
  6. MapMessagemm=session.createMapMessage();
  7. mm.setLong("count",newDate().getTime());
  8. returnmm;
  9. }
  10. });
  11. }
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:

  1. publicstaticvoidmain(String[]args){
  2. ApplicationContextctx=newFileSystemXmlApplicationContext("classpath:app*.xml");
  3. JmsTemplatejmsTemplate=(JmsTemplate)ctx.getBean("jmsTemplate");
  4. while(true){
  5. Map<String,Object>mm=(Map<String,Object>)jmsTemplate.receiveAndConvert();
  6. System.out.println("收到消息:"+newDate((Long)mm.get("count")));
  7. }
  8. }
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

参考资料:

Hello ActiveMQ

Spring2.5整合ActiveMQ 5.2

spring-support

JMS 相关资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值