JMS在Spring框架下的应用

来源:互联网 发布:妮哩萌萌软件 编辑:程序博客网 时间:2024/05/21 22:56
上传通讯薄操作,除了向客户端返回好友列表外,还需要将上传的通讯簿存储到数据库中,以便进行后期数据分析。一开始,我的设计是将通讯薄全部插到数据库后再返回客户端,但经过测试,用户访问速度过慢,于是我就采用多线程处理的方式,单开一个线程,在后台慢慢插去吧,不影响客户端访问速度就行。我对多线程也不是太熟悉,代码设计是参考硕硕的,由于时间紧,也没多思考,虽然用得心里有点不踏实。

    今早刚到公司就被游游责问,“通讯薄存数据库开了多线程,你考虑线程安全了吗”,志东也说,“开了多线程,如果线程池满,怎么办,数据会丢失的。。。”我只能实话实说,当时确实没考虑线程安全问题,代码参考自硕硕。。。志东生气了,“张硕是错的你也抄!”。。。我顿时无语,只怨当时开动线程的时候没多考证一下。唉,痛定思痛,根据志东的建议:不要在Spring的Controller里开多线程,如果想进行异步操作,可使用JMS。。。。

    忙完令人超级蛋疼的LBS的bug,着手对上传通讯薄JMS的优化。看了半下午JMS,照着Demo,JMS算是跑起来了。具体配置下面将详细阐述。

    受教育的一天那。。。有时,犯错,确实会使人进点步。


另:Spring的线程问题,到底怎么个情况,需要好好的搞一搞。线程池?多大?怎么设置的?SPring的线程模型?


    对JMS的一些理解:

    JMS有两种工作模式,vm和tcp,使用vm模式时,不必ActiveMQ服务器。使用tcp时,需要使用ActiveMQ,从而建立Tcp链接。

    ActiveMQ官网下载地址:http://activemq.apache.org/download.html

 

1. 使用jms所需的依赖包

 

    activemq-all-5.3.0.jar

    activemq-web-5.3.0.jar

    geronimo-j2ee-management_1.0_spec-1.0.jar

    geronimo-jms_1.1_spec-1.1.1.jar

    geronimo-jta_1.0.1B_spec-1.0.1.jar

 

2. 搭好Spring环境

 

    略

 

3. 配置

 

    这里主要介绍使用Spring监听来实现异步接受消息。

 

    (1) applicationContext-jms.xml

 

Xml代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:util="http://www.springframework.org/schema/util"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd   
  6.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd   
  7.         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">  
  8.     <!-- 消息中介-->  
  9.     <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">  
  10.         <property name="brokerURL" value="vm://localhost"/>  
  11.     </bean>  
  12.     <!-- 队列目的地-->  
  13.     <bean id="myQueue" class="org.apache.activemq.command.ActiveMQQueue">  
  14.         <constructor-arg index="0" value="notifyQueue"/>  
  15.     </bean>  
  16.     <!-- 订阅目的地-->  
  17.     <bean id="myTopic" class="org.apache.activemq.command.ActiveMQTopic">  
  18.         <constructor-arg index="0" value="notifyTopic"/>  
  19.     </bean>  
  20.     <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
  21.         <property name="connectionFactory" ref="connectionFactory"/>  
  22.         <!-- 设置默认的消息目的地-->  
  23.         <property name="defaultDestination" ref="myQueue"/>  
  24.         <!-- 由于receiver方法是同步的,所以我们在这里对接收设置超时时间-->  
  25.         <property name="receiveTimeout" value="60000"/>  
  26.     </bean>  
  27.        
  28.     <!-- 消息发送者-->  
  29.     <bean id="producer" class="com.sszd.springjms.JMSProducer">  
  30.         <property name="jmsTemplate" ref="jmsTemplate"/>  
  31.         <!-- 消息目的地,因为jmsTemplate有默认的了,所以这里可以省略   
  32.         <property name="destination" ref=" myQueue "/>-->  
  33.     </bean>  
  34.        
  35.     <!-- 消息接收监听器用于异步接收消息-->  
  36.     <bean class="org.springframework.jms.listener.SimpleMessageListenerContainer">  
  37.         <property name="connectionFactory" ref="connectionFactory"/>  
  38.         <property name="destination" ref="myQueue"/>  
  39.         <!--  <property name="messageListener" ref="studentMDP"/>-->  
  40.         <property name="messageListener" ref="pureMDPAdapter"/>  
  41.            
  42.     </bean>  
  43.     <!-- 消息监听实现方法一 -->  
  44.     <bean id="studentMDP" class="com.sszd.springjms.StudentMDP"/>  
  45.        
  46.     <!-- 消息监听实现方法二,使用POJO -->  
  47.     <bean id="pureMDPAdapter" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">  
  48.         <property name="delegate" ref="pureStudentMDP"/>  
  49.         <property name="defaultListenerMethod" value="process"/>  
  50.     </bean>  
  51.     <!-- 消息驱动pojo -->  
  52.     <bean id ="pureStudentMDP" class="com.sszd.springjms.PureStudentMDP" >  
  53.         <!--可以配置Spring的依赖   
  54.         <property name="springOperation" ref="springOperation"/>  
  55.         -->  
  56.     </bean>  
  57.        
  58. </beans>  

 

    (2) 消息生产者

 

Java代码 复制代码 收藏代码
  1. package com.sszd.springjms;   
  2.   
  3. import javax.jms.JMSException;   
  4. import javax.jms.MapMessage;   
  5. import javax.jms.Message;   
  6. import javax.jms.Session;   
  7. import org.springframework.jms.core.JmsTemplate;   
  8. import org.springframework.jms.core.MessageCreator;   
  9.   
  10. import com.neu.edu.model.Student;   
  11.   
  12. /**  
  13.  * 利用Spring中的JmsTemplate产生消息  
  14.  *   
  15.  */  
  16. public class JMSProducer {   
  17.     private JmsTemplate jmsTemplate;   
  18.   
  19.     public JmsTemplate getJmsTemplate() {   
  20.         return jmsTemplate;   
  21.     }   
  22.   
  23.     public void setJmsTemplate(JmsTemplate jmsTemplate) {   
  24.         this.jmsTemplate = jmsTemplate;   
  25.     }   
  26.   
  27.     // 传送一个Student 对象(重写了toString()方法)   
  28.     public void send(final Student student) {   
  29.         this.jmsTemplate.send(new MessageCreator() {   
  30.             public Message createMessage(Session session) throws JMSException {   
  31.                 MapMessage message = session.createMapMessage();   
  32.                 message.setString("key1", student.getName());   
  33.                 message.setString("key2", student.getAge());   
  34.                                 //也可以直接发送对象,对象必须是可序列化的  
  35.                                 //ObjectMessage message = session.createObjectMessage();  
  36.                                 //message.setObject(student);  
  37.                 return message;   
  38.             }   
  39.         });   
  40.     }   
  41. }  

 

    (3) 消息接受监听器实现

 

    方法一:

 

Java代码 复制代码 收藏代码
  1. package com.sszd.springjms;   
  2.   
  3. import javax.jms.JMSException;   
  4. import javax.jms.MapMessage;   
  5. import javax.jms.Message;   
  6. import javax.jms.MessageListener;   
  7.   
  8. import com.neu.edu.model.Student;   
  9.   
  10. /**  
  11.  * 消息监听类  
  12.  * */  
  13. public class StudentMDP implements MessageListener {   
  14.     public void onMessage(Message message) {   
  15.         MapMessage mapMessage = (MapMessage) message;   
  16.         Student student = new Student();   
  17.         try {   
  18.             student.setName(mapMessage.getString("key1"));   
  19.             student.setAge(mapMessage.getString("key2"));   
  20.             try {   
  21.                 Thread.sleep(1000);   
  22.             } catch (InterruptedException e) {   
  23.                 e.printStackTrace();   
  24.             }   
  25.             System.out.println(student.getName());   
  26.         } catch (JMSException e) {   
  27.             e.printStackTrace();   
  28.         }   
  29.     }   
  30. }  

    

    方法二(使用POJO):

 

Java代码 复制代码 收藏代码
  1. package com.sszd.springjms;   
  2.   
  3. import java.util.Map;   
  4.   
  5. import com.neu.edu.model.Student;   
  6.   
  7. /**  
  8.  *纯POJO实现消息接收  
  9.  * */  
  10. public class PureStudentMDP {   
  11.     //private PoiDataFromProviderService poiDataFromProviderService;可以添加Spring依赖注入  
  12.     public void process(Map map) {   
  13.         Student student = new Student();   
  14.         student.setName((String) map.get("key1"));   
  15.         student.setAge((String) map.get("key2"));   
  16.         System.out.println("PureStudentMDP:");   
  17.         System.out.println(student);   
  18.     }   
  19. /*可以直接接收对象  
  20.     public void process(Objec obj) {  
  21.         Student student = (Student)obj;  
  22.         System.out.println(student);  
  23.     }  
  24. */  
  25.   
  26. }  

 

    (4) 业务层调用及配置

    xml配置

Xml代码 复制代码 收藏代码
  1. <bean name="jmsLogic" class="com.neu.edu.controllers.JMSLogic">  
  2.         <property name="jmsProducer" ref="producer"/>  
  3. </bean>  

    业务层调用:

Java代码 复制代码 收藏代码
  1.        。。。   
  2.       private JMSProducer jmsProducer;   
  3.   
  4. public void upload() {   
  5.     。。。   
  6.     Student student = new Student();   
  7.     for (int i = 0; i < 15; i++) {   
  8.         student.setName("zzq" + i);   
  9.         student.setAge("25");   
  10.         jmsProducer.send(student);   
  11.         System.out.println("消息已经发送.....");   
  12.     }   
  13. }   
  14.        。。。  

 

4. 说明

    本示例参考自百度文库的资料(见附件Spring中使用JMS.pdf http://wenku.baidu.com/view/98242d75f46527d3240ce0cc.html ),关于JMS的深入学习,将在后续章节补充。

 

http://www.blogjava.net/heyang/archive/2009/09/24/296254.html

  • jms.rar (5.3 MB)
  • 下载次数: 167
  • Spring中使用JMS.pdf (243.4 KB
0 0
原创粉丝点击