读书人

Spring整跟ActiveMQ

发布时间: 2012-11-08 08:48:12 作者: rapoo

Spring整和ActiveMQ

问题一:为什么要整合ActiveMQ?

????? 传统的JDBC代码在处理连接、语句、结果集和异常时是多么冗长和繁杂你一定不会忘记,传统的JMS继承了JDBC的“关荣传统”。发送一个简单的消息,要几行代码呢?请仔细数数吧。

public void sendMessage() throws JMSException {ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");Connection connection = null;Session session=null;try {connection = (Connection) connectionFactory.createConnection();//创建连接session = (Session) connection.createSession(false,Session.AUTO_ACKNOWLEDGE);//创建会话Destination destination = session.createQueue("myQueue");MessageProducer producer = session.createProducer(destination);TextMessage message = session.createTextMessage(expectedBody);message.setStringProperty("headname", "remoteB");producer.send(message);connection.close();} catch (Exception e) {e.printStackTrace();}finally{try {if(session!=null){session.close();}if(connection!=null){connection=null;}} catch (Exception e) {}}}

?

传统接受消息而是类似的代码,其实我们的目的就是发送和接受消息。幸运的是Spring为我们提供了大量的模板。项目一期用的较多的是JdbCTemplate,spring也为我们提供了JMSTemplate模板。

?

问题二:JMSTemplate模板该如何配置呢?

类似于jdbcTemplate,首先要配置一个ConnectionFactory,我们采用ActiveMQ5.2作为消息服务器。之后要开始配置JmsTemplate模板了。最后是配置消息目标了。消息分为队列和主题两大类,因此要配置两个消息目标了。

?

<!-- ActiveMQ -->        <!-- 配置JMS连接工厂 -->      <bean id="JmsConnectionFactory" value="tcp://localhost:61616"/>      </bean>      <!-- 配置JMS模版 -->      <bean id="JmsTemplate" ref="JmsConnectionFactory"/>      </bean>      <!-- 发送消息的目的地(队列) -->      <bean id="QueueDestination" value="HelloWorldQueue"/>      </bean>    <!-- 发送消息的目的地(主题) -->      <bean id="TopicDestination" value="FlexTopic"/>      </bean>   

?

问题三:如何使用JmsTemplate发送消息呢?

spring的beanfactory得到一个jmsTemplate的实例和消息目标的实例,发送消息,够简单的吧。看看代码:

JmsTemplate template = (JmsTemplate) SpringContext.getBean("JmsTemplate");ActiveMQTopic destination=(ActiveMQTopic)SpringContext.getBean("TopicDestination");template.send((javax.jms.Destination) destination, new MessageCreator(){public Message createMessage(Session session) throws JMSException {return session.createTextMessage("hello");}});

?问题四:上面的代码能不能在简单些?

很多时候,发送消息的目标都是默认的,因此是不是可以在jmsTemplate中设置一个默认的消息目标呢?答案是肯定的。

 <!-- 配置JMS模版 -->      <bean id="JmsTemplate" ref="JmsConnectionFactory"/>    <property name="defaultDestination" ref="TopicDestination"></property>    </bean> 

?

发送消息的时候,不指定目标,spring就会调用默认的目标了。

JmsTemplate template = (JmsTemplate) SpringContext.getBean("JmsTemplate");template.send( new MessageCreator(){public Message createMessage(Session session) throws JMSException {return session.createTextMessage("hello");}});

?

问题四:jmsTemplate怎么接受信息?

?

jmsTemplate接收消息十分的简单,只需要调用template.receive()方法,receive方法是同步的,默认情况下,对receive()方法的调用会造成阻塞,知道消息到达目标----如果必要,永远等下去。为了避免对消息内容等待,可以配置jmsTemplate时,通过设置receiveTimeout属性来指定接收消息超时时间。下面的配置将接收消息的超时时间设置为一分钟(60000毫秒)。

 <!-- 配置JMS模版 -->      <bean id="JmsTemplate" ref="JmsConnectionFactory"/>    <property name="defaultDestination" ref="TopicDestination"></property>    <property name="receiveTimeout" value="60000"></property>    </bean>  

?

?template.receive()会从默认目标接收消息,如果你希望指定一个目标,可以传一个目标。如:template.receive("myQueue").

同步接收消息并不是spring唯一的选择,消息监听器可以实现异步(下篇文章将会介绍消息驱动)。

?

问题五:怎么自动将消息转化为Java对象?

?

转化器在很多组件中都是必不缺少的东西。Spring挺过MessageConverter接口提供了对消息转换的支持。

public class MyMessageConverter implements MessageConverter {@Overridepublic Object fromMessage(Message arg0) throws JMSException,MessageConversionException {// TODO Auto-generated method stubreturn null;}@Overridepublic Message toMessage(Object arg0, Session arg1) throws JMSException,MessageConversionException {// TODO Auto-generated method stubreturn null;}}

?

MessageConverter接口的两个方法简单明了。在发送端toMessage会将java对象转化为消息,在接收端fromMessage会将消息转化为java对象。

下面的代码简单的实现了MessageConverter的两个接口。

public class MyMessageConverter implements MessageConverter {@Overridepublic Object fromMessage(Message message) throws JMSException,MessageConversionException {if(!(message instanceof MapMessage)){throw new MessageConversionException("Messae is not MapMessage");}MapMessage mapMessage=(MapMessage)message;MessageObj messageObj=new MessageObj();messageObj.setId(mapMessage.getString("id"));messageObj.setInfo(mapMessage.getString("info"));return messageObj;}@Overridepublic Message toMessage(Object obj, Session session) throws JMSException,MessageConversionException {if(!(obj instanceof MessageObj)){throw new MessageConversionException("obj is not MessageObj");}MessageObj messageObj=(MessageObj)obj;MapMessage mapMessage=session.createMapMessage();mapMessage.setString("id", messageObj.getId());mapMessage.setString("info", messageObj.getInfo());return mapMessage;}}

?

此时,发送和接收消息要换成template.convertAndSend(message);template.receiveAndConvert();

可是jmsTemplate如何知道消息转换器呢?需要在配置jmsTemplate的时候,加上messageConverter属性。

 <!-- 配置JMS模版 -->      <bean id="JmsTemplate" ref="JmsConnectionFactory"/>    <property name="defaultDestination" ref="TopicDestination"></property>    <property name="receiveTimeout" value="60000"></property>    <property name="messageConverter" ref="messageObj"></property>    </bean>  

?messageObj是要转化的java对象的bean的id。

读书人网 >软件架构设计

热点推荐