JMS学习(二)activeMQ
来源:互联网 发布:daemontools linux 编辑:程序博客网 时间:2024/04/30 07:57
1.JMS之activeMQ
由于最近比较的忙, 暂时没有更新,稍后有时间更新和spring的整合,关于activemq更深层次的,在今后的时间和大家一起学习了
2015-05-30,眼看就月底了,一个月该做的是还是要努力的完成,做人做事要有始有终,定的计划就要努力完成。
之前的一篇文章简单的介绍了下JMS以及activeMQ的一个入门,这篇就总结和activeMQ的使用
话不多说, 先上一个例子,然后再慢慢分析,我习惯先看到东西, 再来慢慢了解他,这样理解更加形象。
2.实例分析
spring整合activemq就是把连接工厂和创建连接的事交由spring处理,然后使用JmsTemplate做收发消息
2.1实例
spring-activemq.xml 配置如下:
<!-- ActiveMQ 连接 --> <bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616" /> <property name="useAsyncSend" value="true"/> </bean> <!-- Spring用于管理真正的ConnectionFactory的ConnectionFactory --> <bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory"> <!-- 目标ConnectionFactory对应真实的可以产生JMS Connection的ConnectionFactory --> <property name="targetConnectionFactory" ref="targetConnectionFactory"/> </bean> <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue"> <constructor-arg index="0" value="myqueue"></constructor-arg> </bean> <!-- <bean id="myMessageConverter" class="fun.activemq.myMessageConverter"></bean> --> <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="connectionFactory"></property> <property name="defaultDestination" ref="destination"></property> <!-- <property name="messageConverter" ref="myMessageConverter"></property> --> </bean> <bean id="messageListener" class="fun.spring_activemq.MyMessageListener"></bean> <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" lazy-init="false"> <property name="connectionFactory" ref="connectionFactory"></property> <property name="destination" ref="destination"></property> <property name="messageListener" ref="messageListener"></property> <!-- 0:CACHE_NONE,1:CACHE_CONNECTION,2:CACHE_SESSION,3:CACHE_CONSUMER,4:CACHE_AUTO --> <property name="cacheLevel" value="0"/> </bean>
Sender.java
package fun.spring_activemq;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.jms.core.JmsTemplate;import org.springframework.jms.core.MessageCreator;import org.springframework.stereotype.Component;@Component("sender")public class Sender{ @Autowired private JmsTemplate jmsTemplate; public void sendMsg(Destination destination,final String message){ jmsTemplate.send(destination,new MessageCreator() { @Override public Message createMessage(Session session) throws JMSException { return session.createTextMessage(message); } }); }}
接收消息者:这里整合的时候使用的是异步接收消息的,使用实现MessageListener接口的java类
MyMessageListener.java
“`java
package fun.spring_activemq;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
public class MyMessageListener implements MessageListener{
@Overridepublic void onMessage(Message message) { // TODO implement MessageListener.onMessage TextMessage textMsg = (TextMessage) message; try { System.out.println("收到消息:"+textMsg.getText()); } catch (JMSException e) { e.printStackTrace(); }}
}
“`
test程序
@Test public void sendMsg(){ ApplicationContext ac = new ClassPathXmlApplicationContext("spring/*.xml"); Sender sender = (Sender) ac.getBean("sender"); Destination destination = (Destination) ac.getBean("destination"); System.out.println("send message: hello activemq"); sender.sendMsg(destination,"hello activemq"); System.out.println("after send message: hello activemq"); }
2.2实例代码分析
- 上面这个例子中sender类里面注入JmsTemplate ,使用jmsTemplate进行发送消息,发送消息的时候从之前的一中说到的可以知道需要一个session,这里使用MessageCreator 这个类,他会使用内部的消息转换器来转换消息。然后返回一个Message,由jmsTemplate来发送。
- 消息接受者是一个MessageListener,实现了MessageListener接口,实现onMessage方法就行了,所以这里可以看出,如果要把消息持久化在数据库中的话,可以在这里进行处理。
- 关于配置,应该很明了,最简单的配置,分别配置了ConnectionFactory,Destination,MessageListener,JmsTemplate和jmsContainer。
可以看出来,其实和我在第一篇文章中写的步骤是差不多的,进过spring处理之后简化了不少步骤
3.spring+activeMQ
3.1 同步消息和异步消息
3.1.1 同步和异步
刚开始使用spring整合的时候我就发现,为什么这个里面没有使用receiver呢,MessageListener就是receiver,那么,这和直接写receiver有什么区别呢?后来和朋友交流才知道是同步和异步方式的问题。
同步的接收消息会使接受者处于阻塞的状态,知道接收到消息的时候为止,相反异步消息不会是应用程序发生阻塞,两种情况具体要看业务的需求,如果应用程序必须要接收到回应之后才做下一步的工作的话,那么我们就该选择使用同步的消息,相反可使用异步的消息
3.1.2 同步异步实现上的区别
不论同步还是发送消息的写法总是一样,唯一不同的是接受者的实现方式,如果使用MessageListener接口的话,这时就是一个异步接收消息的实现,如果使用自己写一个receiver的话,就如同JMS学习(一) 中的写法一样,使用循环接听接收消息,但是使用jmsTemplate的receive方法,类似使用send方法,这个方法是一个阻塞的方法,这个类似c/c++中网络编程中的receive一样。
3.2 Connectionfactory
在一本上上看到 JNDI factory之类的,不是很会用,可以再在网上查阅
一般我就使用例子中的集成方式,又activeMQ提供工厂,spring的SingleConnectionFactory 管理就行
3.3 JmsTemplate
使用过spring的都知道,spring在整合各种框架的时候都会提供一个叫做 xxxTemplate 的一个操作工具,帮助开发人员减少重复的代码,这里也是一样的,jmsTemplate就是发送和接收消息的模板。了解jmsTemlate,就需要了解他的一些方法
接受消息的方法类似,对应的有 receiver ,receiverandconvert,receiverseleced
其中不同的就是receiverselected可以对要接受的消息进行筛选,例如接受优先级大于4的消息
Message msg = jmsTemplate.receiverselected(“JMSPriority > 4”);
具体用法就查阅API啦
3.4 消息转换器
说消息转换器之前先说说消息。
消息类型
在activeMQ中的有
转换器实现
在上面说到了使用 带convert**的方法的时候,就会调用内部消息转换器对应的进行转换,如果不想使用内部消息转换器的话,就自己实现消息转换器
实现MessageConverter接口,实现里面的fromMessage和toMessage就可以了,然后再spring的配置文件中把这个bean**注入到JmsTemplate**就可以了,如同上面配置文件中被注释的代码。
3.5 MessageListener
消息侦听器需要注入到消息容器(JmsContainer)中才起作用,实现MessageListener的方法有3,
1. javax.jms.MessageListener ,实现这个接口的类
2. Spring的SeesionAwareMessageListener ,实现这个接口
3. 使用spring提供的MessageListenerAdapter
3.5.1 SeesionAwareMessageListener
三者的区别在于,如果在接受到消息之后需要拿到session对象来进行一些操作,这个时候sessionAwarelistener可以获得这个对象,例如拿到消息后需要作出回信,这个时候代码如下:
//消息接受完//.....//回应MessageProducer producer = session.createProducer(message.getJMSReplyto());TextMessage msg = session.createTextMessage();msg.setJMSCorrelationID(message.getJMSMessageID());msg.setText("message "+message.getJMSMessageID()+" received" );producer.send(msg);
3.5.2 MessageListenerAdapter
使用这个类的时候,可以将任何一个普通的java类的某个方法做为接受方法,单作为接受方法的类的参数类型要是对用消息类型的java类型,例如: handlerMessage(String msg)就只接受TextMessage了。
这是spring的Messagelistener的配置使用
<bean id="messageListener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter"> <constructor-arg> <bean class="fun.spring_activemq.MyListener"></bean> </constructor-arg> <!-- <property name="defaultListenerMethod" value="defaultReceive"></property> --> </bean>
使用 指明接收消息的类,还可以使用上面注释的部分来指明具体方法(要保证java类有此方法)
3.6 JmsContainer
JmsContainer的实现有两个
- DefaultMessageListnerContainer –>支持并发,动态调整线程数,和分布式事务可集成
- SimpleMessageListnerContainer –> 支持并发,本地事务集成
基出就差不多,关于activemq更深的东西就在应用中慢慢掌握加以深刻理解,熟练运用了。
- JMS学习(二)activeMQ
- JMS学习二(简单的ActiveMQ实例)
- JMS学习二(简单的ActiveMQ实例)
- ActiveMQ学习(一)--JMS及ActiveMQ
- JMS ActiveMQ学习(一)
- web JMS学习(activeMq)
- ActiveMQ学习笔记(二) JMS与Spring
- JMS学习二: 启动ActiveMQ 服务
- (二)MQ、JMS以及ActiveMQ
- ActiveMQ 介绍(二)之JMS
- ActiveMQ-JMS(二):发送消息
- ActiveMQ(二)-Spring集成JMS
- JMS探讨二 ActiveMq
- JMS Activemq (二)
- JMS(ActiveMQ)学习以及分析
- JMS学习四(ActiveMQ消息过滤)
- JMS学习九(ActiveMQ集群)
- JMS学习十三(ActiveMQ安全)
- 4-链表删除-图解
- java.lang.ClassNotFoundException: org.springframework.http.converter.json.MappingJacksonHttpMessageC
- 【汇编】学习笔记——第四篇
- 二元选择排序
- JMS学习(一)入门及activemq简单实例
- JMS学习(二)activeMQ
- 五子棋1.0版,c++初学
- 美国研究:穷养孩子难翻身
- C判断一个正整数n的d进制数是否是回文数
- 我们为什么需要Map-Reduce?
- 曾经轰动全球的短文,关于年轻人的梦想
- Same Tree Leetcode c#
- 碟对碟!《身份》《无声处》同天发布会
- 利用Spring AOP 更新Memcached 缓存策略的实现