Spring整和ActiveMQ

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

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

Java代码   收藏代码
  1. public void sendMessage() throws JMSException {  
  2.     ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(  
  3.     "tcp://localhost:61616");  
  4.     Connection connection = null;  
  5.     Session session=null;  
  6.     try {  
  7.           
  8.         connection = (Connection) connectionFactory.createConnection();//创建连接  
  9.         session = (Session) connection.createSession(false,  
  10.                 Session.AUTO_ACKNOWLEDGE);//创建会话  
  11.         Destination destination = session.createQueue("myQueue");  
  12.         MessageProducer producer = session.createProducer(destination);  
  13.         TextMessage message = session.createTextMessage(expectedBody);  
  14.         message.setStringProperty("headname""remoteB");  
  15.         producer.send(message);  
  16.         connection.close();  
  17.     } catch (Exception e) {  
  18.         e.printStackTrace();  
  19.     }finally{  
  20.         try {  
  21.             if(session!=null){  
  22.                 session.close();  
  23.             }  
  24.             if(connection!=null){  
  25.                 connection=null;  
  26.             }  
  27.         } catch (Exception e) {  
  28.               
  29.         }  
  30.     }  
  31. }  

 

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

 

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

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

 

Java代码   收藏代码
  1. <!-- ActiveMQ -->  
  2.       
  3.     <!-- 配置JMS连接工厂 -->    
  4.     <bean id="JmsConnectionFactory" class="org.apache.activemq.spring.ActiveMQConnectionFactory">    
  5.         <property name="brokerURL" value="tcp://localhost:61616"/>    
  6.     </bean>    
  7.     <!-- 配置JMS模版 -->    
  8.     <bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">    
  9.         <property name="connectionFactory" ref="JmsConnectionFactory"/>    
  10.     </bean>    
  11.     <!-- 发送消息的目的地(队列) -->    
  12.     <bean id="QueueDestination" class="org.apache.activemq.command.ActiveMQQueue">    
  13.         <!-- 设置消息队列的名字 -->    
  14.         <constructor-arg index="0" value="HelloWorldQueue"/>    
  15.     </bean>  
  16.     <!-- 发送消息的目的地(主题) -->    
  17.     <bean id="TopicDestination" class="org.apache.activemq.command.ActiveMQTopic">    
  18.         <!-- 设置消息主题的名字 -->    
  19.         <constructor-arg index="0" value="FlexTopic"/>    
  20.     </bean>     

 

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

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

Java代码   收藏代码
  1. JmsTemplate template = (JmsTemplate) SpringContext.getBean("JmsTemplate");  
  2.             ActiveMQTopic destination=(ActiveMQTopic)SpringContext.getBean("TopicDestination");  
  3.             template.send((javax.jms.Destination) destination, new MessageCreator(){  
  4.                 public Message createMessage(Session session) throws JMSException {  
  5.                     return session.createTextMessage("hello");  
  6.                 }  
  7.                   
  8.             });  

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

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

Java代码   收藏代码
  1. <!-- 配置JMS模版 -->    
  2.    <bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">    
  3.     <property name="connectionFactory" ref="JmsConnectionFactory"/>  
  4.     <property name="defaultDestination" ref="TopicDestination"></property>  
  5.    </bean>   

 

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

Java代码   收藏代码
  1. JmsTemplate template = (JmsTemplate) SpringContext.getBean("JmsTemplate");  
  2.             template.send( new MessageCreator(){  
  3.                 public Message createMessage(Session session) throws JMSException {  
  4.                     return session.createTextMessage("hello");  
  5.                 }  
  6.             });  

 

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

 

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

Xml代码   收藏代码
  1. <!-- 配置JMS模版 -->    
  2.    <bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">    
  3.     <property name="connectionFactory" ref="JmsConnectionFactory"/>  
  4.     <property name="defaultDestination" ref="TopicDestination"></property>  
  5.     <property name="receiveTimeout" value="60000"></property>  
  6.    </bean>    

 

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

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

 

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

 

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

Java代码   收藏代码
  1. public class MyMessageConverter implements MessageConverter {  
  2.     @Override  
  3.     public Object fromMessage(Message arg0) throws JMSException,  
  4.             MessageConversionException {  
  5.         // TODO Auto-generated method stub  
  6.         return null;  
  7.     }  
  8.     @Override  
  9.     public Message toMessage(Object arg0, Session arg1) throws JMSException,  
  10.             MessageConversionException {  
  11.         // TODO Auto-generated method stub  
  12.         return null;  
  13.     }  
  14. }  

 

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

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

Java代码   收藏代码
  1. public class MyMessageConverter implements MessageConverter {  
  2.     @Override  
  3.     public Object fromMessage(Message message) throws JMSException,  
  4.             MessageConversionException {  
  5.         if(!(message instanceof MapMessage)){  
  6.             throw new MessageConversionException("Messae is not MapMessage");  
  7.         }  
  8.         MapMessage mapMessage=(MapMessage)message;  
  9.         MessageObj messageObj=new MessageObj();  
  10.         messageObj.setId(mapMessage.getString("id"));  
  11.         messageObj.setInfo(mapMessage.getString("info"));  
  12.         return messageObj;  
  13.     }  
  14.     @Override  
  15.     public Message toMessage(Object obj, Session session) throws JMSException,  
  16.             MessageConversionException {  
  17.         if(!(obj instanceof MessageObj)){  
  18.             throw new MessageConversionException("obj is not MessageObj");  
  19.         }  
  20.         MessageObj messageObj=(MessageObj)obj;  
  21.         MapMessage mapMessage=session.createMapMessage();  
  22.         mapMessage.setString("id", messageObj.getId());  
  23.         mapMessage.setString("info", messageObj.getInfo());  
  24.         return mapMessage;  
  25.     }  
  26. }  

 

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

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

Java代码   收藏代码
  1. <!-- 配置JMS模版 -->    
  2.    <bean id="JmsTemplate" class="org.springframework.jms.core.JmsTemplate">    
  3.     <property name="connectionFactory" ref="JmsConnectionFactory"/>  
  4.     <property name="defaultDestination" ref="TopicDestination"></property>  
  5.     <property name="receiveTimeout" value="60000"></property>  
  6.     <property name="messageConverter" ref="messageObj"></property>  
  7.    </bean>    

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值