`

jboss + JMS 开发实例

阅读更多
核心提示:异步进程通信是面向服务架构(SOA)一个重要的组成部分,因为企业里很多系统通信,特别是与外部组织间的通信,实质上都是异步的。Java消息服务(JMS)是用于编写使用异步消息传递的JEE应用程序的API。传统的使用JMS API进行消息传递的实现包括多个步骤,例如JNDI

   异步进程通信是面向服务架构(SOA)一个重要的组成部分,因为企业里很多系统通信,特别是与外部组织间的通信,实质上都是异步的。Java消息服务(JMS)是用于编写使用异步消息传递的JEE应用程序的API。传统的使用JMS API进行消息传递的实现包括多个步骤,例如JNDI查询队列连接工厂和Queue资源,在实际发送和接收消息前创建一个JMS会话。
   Spring框架则简化了使用JEE组件(包括JMS)的任务。它提供的模板机制隐藏了典型的JMS实现的细节,这样开发人员可以集中精力放在处理消息的实际工作中,而不用担心如何去创建,访问或清除JMS资源。

   本文将对Spring JMS API作一个概述,并通过一个运行在JBoss MQ服务器上的web例程来介绍如何使用Spring JMS API来异步处理(发送和接收)消息。我将通过传统JMS实现和Spring JMS实现两者间的比较,来展示使用Spring JMS处理消息是如何的简单和灵活。

异步消息传递和面向服务架构
  在现实中,大多数web请求都是同步处理的。例如,当用户要登入一个网站,首先输入用户名和密码,然后服务器验证登录合法性。如果验证成功,程序将允许该用户进入网站。这里,登录请求在从客户端接收以后被即时处理了。信用卡验证是另一个同步处理的例子;只有服务器证实输入的信用卡号是有效的,同时客户在帐户上有足够的存款,客户才被允许继续操作。但是让我们思考一下在顺序处理系统上的支付结算步骤。一旦系统证实该用户信用卡的信息是准确的,并且在帐户上有足够的资金,就不必等到所有的支付细节落实、转账完成。支付结算可以异步方式进行,这样客户可以继续进行核查操作。

   需要比典型同步请求耗费更长时间的请求,可以使用异步处理。另一个异步处理的例子是,在本地贷款处理程序中,提交至自动承销系统(AUS)的信用请求处理过程。当借方提交贷款申请后,抵押公司会向AUS发送请求,以获取信用历史记录。由于这个请求要求得到全面而又详细的信用报告,包括借方现今和过去的帐户,最近的付款和其他财务资料,服务器需要耗费较长的时间(几小时或着有时甚至是几天)来对这些请求作出响应。客户端程序(应用)要与服务器连接并耗费如此长的时间来等待结果,这是毫无意义的。因此通信应该是异步发生的;也就是,一旦请求被提交,它就被放置在队列中,同时客户端与服务器断开连接。然后AUS服务从指定的队列中选出请求进行处理,并将处理得到的消息放置在另一个消息队列里。最后,客户端程序从这个队列中选出处理结果,紧接着处理这个信用历史数据。

JMS
   如果您使用过JMS代码,您会发现它与JDBC或JCA很像。它所包含的样本代码创建或JMS资源对象回溯,使得每一次您需要写一个新类来发送和接收消息时,都具有更好的代码密集性和重复性。以下序列显示了传统JMS实现所包括的步骤:

创建JNDI初始上下文(context)。
从JNDI上下文获取一个队列连接工厂。
从队列连接工厂中获取一个Quene。
创建一个Session对象。
创建一个发送者(sender)或接收者(receiver)对象。
使用步骤5创建的发送者或接收者对象发送或接收消息。
处理完消息后,关闭所有JMS资源。
您可以看到,步骤6是处理消息的唯一地方。其他步骤都只是管理与实际业务要求无关的JMS资源,但是开发人员必须编写并维护这些额外步骤的代码。

Spring JMS
   Spring框架提供了一个模板机制来隐藏Java APIs的细节。JEE开发人员可以使用JDBCTemplate和JNDITemplate类来分别访问后台数据库和JEE资源(数据源,连接池)。JMS也不例外。Spring提供JMSTemplate类,因此开发人员不用为一个JMS实现去编写样本代码。接下来是在开发JMS应用程序时Spring所具有一些的优势。

提供JMS抽象API,简化了访问目标(队列或主题)和向指定目标发布消息时JMS的使用。
JEE开发人员不需要关心JMS不同版本(例如JMS 1.0.2与JMS 1.1)之间的差异。
开发人员不必专门处理JMS异常,因为Spring为所有JMS异常提供了一个未经检查的异常,并在JMS代码中重新抛出。
示例程序
        说明:因为只是为了演示如何使用spring编写jms的应用,所以本例没有什么实际用途。

        程序功能:MessageProducer.java根据一用户信息产生一个消息发送到 JMS Provider;由MessageConsumer.java接收。

1.在Jboss里配置XML文件创建一个新的JMS provider。
打开位于%JBOSS_HOME%server\default\deploy\jms文件夹下的jbossmq-destinations-service.xml文件,加入以下代码片断:

  1. <!--  Register User Send/Receive Queue  -->  
  2. <mbean code="org.jboss.mq.server.jmx.Queue"  
  3.   name="jboss.mq.destination:service=Queue,name=registerUserQueue">  
  4.   <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>  
  5. </mbean>  
  6. <!--  Register User Send/Receive Topic  -->  
  7. <mbean code="org.jboss.mq.server.jmx.Topic"  
  8.  name="jboss.mq.destination:service=Topic,name=registerUserTopic">  
  9.   <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>  
  10. </mbean>  


2.在spring的配置文件中配置JMS组件的具体细节。
 (1)JNDI上下文是取得JMS资源的起始位置,因此首先我们要配置JNDI模板:

  1. <!-- JNDI上下文(它是取得JMS资源的起始位置) -->  
  2. bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">  
  3. <property name="environment">  
  4.  <props>  
  5.   <prop key="java.naming.factory.initial">  
  6.    org.jnp.interfaces.NamingContextFactory   
  7.   </prop>  
  8.   <prop key="java.naming.provider.url">localhost</prop>  
  9.   <prop key="java.naming.factory.url.pkgs">  
  10.    org.jnp.interfaces:org.jboss.naming   
  11.   </prop>  
  12.  </props>  
  13. </property>  
  14. /bean>  


   注意:此JNDI模板用到了org.jnp.interfaces.NamingContextFactory所以要把%JBOSS_HOME%\client下的jbossall-client.jar加到你的项目的classpath中。
(2)配置连接工厂:

  1. <!-- JMS连接工厂 -->  
  2.   <bean id="jmsConnectionFactory"class="org.springframework.jndi.JndiObjectFactoryBean">  
  3.  <property name="jndiTemplate">  
  4.   <ref bean="jndiTemplate" />  
  5.  </property>  
  6.  <property name="jndiName">  
  7.   <value>XAConnectionFactory</value>  
  8.  </property>  
  9. </bean>  


   注意:XAConnectionFactory这个JNDI名字是在%JBOSS_HOME%server\default\deploy\jms文件夹下的jms-ds.xml中定义的(它是由JBoss指定的)。
 (3)配置JmsTemplate组件。在例程中我们使用JmsTemplate102。同时使用defaultDestination属性来指定JMS目标。

  1. <!-- JMS模板配置 -->  
  2. <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate102">  
  3.  <property name="connectionFactory" ref="jmsConnectionFactory" />  
  4.  <property name="defaultDestination" ref="destination" />  
  5.  <property name="pubSubDomain">  
  6.   <value>true</value>  
  7.  </property>  
  8.  <!-- 等待消息的时间(ms) -->  
  9.  <property name="receiveTimeout">  
  10.        <value>30000</value>  
  11.     </property>  
  12. </bean>  


  注意:如果使用topic-subscribe(主题订阅)模式,该模板的pubSubDomain属性值为true;若使用PToP(点对点)模式,pubSubDomain属性值为false或不配置该属性。
 (4)定义一个JMS目标来发送和接收消息:

  1. <bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean">  
  2.  <property name="jndiTemplate">  
  3.   <ref bean="jndiTemplate" />  
  4.  </property>  
  5.  <property name="jndiName">  
  6.   <value>topic/registerUserTopic</value>  
  7.  </property>  
  8. </bean>  


 (5)配置发送者和接收者组件:

  1. <!-- 消息发布者 -->  
  2. <bean id="msgProducer" class="com.boco.jms.MessageProducer">  
  3.  <property name="jmsTemplate" ref="jmsTemplate" />  
  4. </bean>  
  5. <!-- 消息接收者 -->  
  6. <bean id="msgConsumer" class="com.boco.jms.MessageConsumer">  
  7.  <property name="jmsTemplate" ref="jmsTemplate" />  
  8. </bean>  


3.相应的类:
 (1). User对象。

  1.  /**  
  2.  *  User.java  
  3.  *  created on Jul 2, 2006  
  4.  *  Copyrights 2006 BOCO,Inc. All rights reserved.  
  5.  */  
  6. package com.boco.dto;   
  7.   
  8. import java.io.Serializable;   
  9.   
  10. /**  
  11.  * desc: 用户信息 Bean  
  12.  * @author qiujy  
  13.  */  
  14. public class User {   
  15.  private int id;   
  16.  private String username;   
  17.  private String password;   
  18.  private String email;   
  19.     
  20.  public User(){}   
  21.     
  22.  //以下为Getter,setter方法略   
  23.  ......   
  24. }  


  
 (2).消息生产者:

  1.  /**  
  2.  *  MessageProducer.java  
  3.  *  created on Jul 22, 2006  
  4.  *  Copyrights 2006 BOCO,Inc. All rights reserved.  
  5.  */  
  6. package com.boco.jms;   
  7.   
  8. import javax.jms.JMSException;   
  9. import javax.jms.MapMessage;   
  10. import javax.jms.Message;   
  11. import javax.jms.Session;   
  12.   
  13. import org.springframework.jms.core.JmsTemplate;   
  14. import org.springframework.jms.core.MessageCreator;   
  15.   
  16. import com.boco.dto.User;   
  17.   
  18. /**  
  19.  * desc:消息生产者  
  20.  * @author qiujy  
  21.  *  
  22.  */  
  23. public class MessageProducer {   
  24.  /** JMS模板 */  
  25.  private JmsTemplate jmsTemplate;   
  26.     
  27.  public void setJmsTemplate(JmsTemplate jmsTemplate){   
  28.   this.jmsTemplate = jmsTemplate;   
  29.  }   
  30.     
  31.  public void sendMessage(final User user){   
  32.   //调用模板的send来发送消息   
  33.   jmsTemplate.send(new MessageCreator(){   
  34.   
  35.    public Message createMessage(Session session) throws JMSException {   
  36.     //构造一个要发送的消息   
  37.     MapMessage message = session.createMapMessage();   
  38.      message.setInt("id", user.getId());   
  39.      message.setString("username", user.getUsername());   
  40.      message.setString("password", user.getPassword());   
  41.      message.setString("email", user.getEmail());   
  42.     System.out.println("send success!!");   
  43.     return message;   
  44.    }   
  45.   });   
  46.  }   
  47. }   

  
 (3).消息消费者:

  1. /**  
  2.  *  MessageConsumer.java  
  3.  *  created on Jul 22, 2006  
  4.  *  Copyrights 2006 BOCO,Inc. All rights reserved.  
  5.  */  
  6. package com.boco.jms;   
  7.   
  8. import javax.jms.JMSException;   
  9. import javax.jms.MapMessage;   
  10.   
  11. import org.springframework.jms.core.JmsTemplate;   
  12.   
  13. import com.boco.dto.User;   
  14.   
  15. /**  
  16.  * desc:消息消费者  
  17.  * @author qiujy  
  18.  *  
  19.  */  
  20. public class MessageConsumer {   
  21.  /** JMS模板 */  
  22.  private JmsTemplate jmsTemplate;   
  23.     
  24.  public void setJmsTemplate(JmsTemplate jmsTemplate){   
  25.   this.jmsTemplate = jmsTemplate;   
  26.  }   
  27.     
  28.  public User receiveMessage(){   
  29.   //参数为Destination的JNDI名字去掉前面的模式类型标识   
  30.   //MapMessage msg = (MapMessage)jmsTemplate.receive("registerUserQueue");   
  31.   MapMessage msg = (MapMessage)jmsTemplate.receive("registerUserTopic");   
  32.   User user = new User();   
  33.      
  34.   try {   
  35.    user.setId(msg.getInt("id"));   
  36.    user.setUsername(msg.getString("username"));   
  37.    user.setPassword(msg.getString("password"));   
  38.    user.setEmail(msg.getString("email"));   
  39.   } catch (JMSException e) {   
  40.    // TODO Auto-generated catch block   
  41.    e.printStackTrace();   
  42.   }   
  43.      
  44.   return user;   
  45.  }   
  46. }  

 (4).测试用例:
   //======== 生产者测试用例 ===============

  1.  /**  
  2.  *  TestMsgProducer.java  
  3.  *  created on Jul 22, 2006  
  4.  *  Copyrights 2006 BOCO,Inc. All rights reserved.  
  5.  */  
  6. package com.boco.jms;   
  7.   
  8. import junit.framework.TestCase;   
  9.   
  10. import org.springframework.context.ApplicationContext;   
  11. import org.springframework.context.support.ClassPathXmlApplicationContext;   
  12.   
  13. import com.boco.dto.User;   
  14.   
  15. /**  
  16.  * desc:  
  17.  * @author qiujy  
  18.  *  
  19.  */  
  20. public class TestMsgProducer extends TestCase {   
  21.   
  22.  private ApplicationContext context;   
  23.  /**  
  24.   * @param arg0  
  25.   */  
  26.  public TestMsgProducer(String arg0) {   
  27.   super(arg0);   
  28.   context = new ClassPathXmlApplicationContext("applicationContext_jms.xml");   
  29.  }   
  30.   
  31.  /* (non-Javadoc)  
  32.   * @see junit.framework.TestCase#setUp()  
  33.   */  
  34.  protected void setUp() throws Exception {   
  35.   super.setUp();   
  36.  }   
  37.   
  38.  /* (non-Javadoc)  
  39.   * @see junit.framework.TestCase#tearDown()  
  40.   */  
  41.  protected void tearDown() throws Exception {   
  42.   super.tearDown();   
  43.  }   
  44.   
  45.  /**  
  46.   * Test method for {@link com.boco.jms.MessageProducer#sendMessage(com.boco.dto.User)}.  
  47.   */  
  48.  public void testSendMessage() {   
  49.   User user = new User();   
  50.   user.setId(132);   
  51.   user.setUsername("JMSTest");   
  52.   user.setPassword("password");   
  53.   user.setEmail("support@boco.com.cn");   
  54.      
  55.   MessageProducer producer = (MessageProducer)context.getBean("msgProducer");   
  56.      
  57.   producer.sendMessage(user);   
  58.      
  59.  }   
  60.   
  61. }  
  1. //============ 消费者测试用例 ===============   
  2. /**  
  3.  *  TestMsgConsumer.java  
  4.  *  created on Jul 22, 2006  
  5.  *  Copyrights 2006 BOCO,Inc. All rights reserved.  
  6.  */  
  7. package com.boco.jms;   
  8.   
  9. import junit.framework.TestCase;   
  10.   
  11. import org.springframework.context.ApplicationContext;   
  12. import org.springframework.context.support.ClassPathXmlApplicationContext;   
  13.   
  14. import com.boco.dto.User;   
  15.   
  16. /**  
  17.  * desc:  
  18.  * @author qiujy  
  19.  *  
  20.  */  
  21. public class TestMsgConsumer extends TestCase {   
  22.  private ApplicationContext context;   
  23.  /**  
  24.   * @param arg0  
  25.   */  
  26.  public TestMsgConsumer(String arg0) {   
  27.   super(arg0);   
  28.   context = new ClassPathXmlApplicationContext("applicationContext_jms.xml");   
  29.  }   
  30.   
  31.  /* (non-Javadoc)  
  32.   * @see junit.framework.TestCase#setUp()  
  33.   */  
  34.  protected void setUp() throws Exception {   
  35.   super.setUp();   
  36.  }   
  37.   
  38.  /* (non-Javadoc)  
  39.   * @see junit.framework.TestCase#tearDown()  
  40.   */  
  41.  protected void tearDown() throws Exception {   
  42.   super.tearDown();   
  43.  }   
  44.   
  45.  /**  
  46.   * Test method for {@link com.boco.jms.MessageConsumer#receiveMessage()}.  
  47.   */  
  48.  public void testReceiveMessage() {   
  49.   MessageConsumer consumer = (MessageConsumer)context.getBean("msgConsumer");   
  50.   User user = consumer.receiveMessage();   
  51.   assertNotNull(user);   
  52.   System.out.println( "id========" + user.getId()   
  53.       + "\nname======" + user.getUsername()   
  54.       + "\npassword==" + user.getPassword()   
  55.       + "\nemail=====" + user.getEmail());   
  56.  }   
  57.   
  58. }  

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liuzhenwen/archive/2009/01/13/3768766.aspx

分享到:
评论

相关推荐

    工作流框架JBoss+jBPM+jPDL用户开发手册

    1. JBoss:JBoss是一个开源的应用服务器,基于Java EE(Java Platform, Enterprise Edition)标准,提供了一系列的企业级服务,如事务管理、安全管理、JMS消息队列等。它为开发者提供了全面的中间件平台,支持Web...

    JBoss+jBPM+jPDL用户开发手册_3.2.3

    首先,JBoss是一个开源的应用服务器,它是Java EE(Enterprise Edition)标准的实现,提供了诸如EJB(Enterprise JavaBeans)、JMS(Java Message Service)和JPA(Java Persistence API)等核心服务,用于构建和...

    JBOSS建立JMS应用实例(附源码)

    下面我们将深入探讨如何在JBoss中构建JMS应用,并通过实例来了解其工作原理。 1. **JMS基础** - **消息模型**:JMS提供了两种主要的消息模型——点对点(Point-to-Point,P2P)和发布/订阅(Publish/Subscribe,...

    JBoss+jBPM+jPDL用户开发手册

    它支持多种服务,包括EJB(Enterprise JavaBeans)、JMS(Java Message Service)、JPA(Java Persistence API)和JSF(JavaServer Faces)等,为开发人员提供了丰富的功能。 【jBPM】 jBPM是Java Business Process...

    jboss服务器下的jms实例

    【JBoss 服务器下的 JMS 实例】 Java 消息服务 (JMS) 是 Java 平台中用于处理异步消息传递的标准API,它在面向服务架构 (SOA) 中扮演着关键角色,特别是在需要与外部系统进行异步通信的企业环境中。JBoss 服务器...

    Jboss ESB简介及开发实例

    **JBoss ESB开发实例** 在实际开发中,使用JBoss ESB通常涉及以下步骤: 1. **环境配置**:首先,需要下载并安装JBoss ESB服务器,配置相应的环境变量,确保服务器正常启动。 2. **服务创建**:创建服务提供者,...

    在jboss同时启动两个实例

    ### 如何在JBoss上同时启动两个实例 在企业级应用服务器JBoss中,有时我们需要在同一台物理机器上运行多个独立的JBoss实例。这在测试环境或开发环境中非常常见,尤其是在进行集成测试或者需要模拟多节点集群环境时...

    jboss7 + EJB3

    JBOSS7是Red Hat公司开发的一款开源Java应用服务器,它基于Java EE 6(Enterprise JavaBeans 3.1)规范,提供了全面的中间件服务,包括Servlet、JSP、JSF、EJB、JMS等。EJB3是Java EE平台中的一个核心组件,它极大地...

    ejb-jboss-web实例的workspace

    【ejb-jboss-web实例的workspace】是一个专用于开发和部署EJB(Enterprise JavaBeans)与Web应用程序的工作环境,基于JBoss应用服务器。这个工作空间集合了开发所需的各种组件、配置文件以及源代码,便于开发者进行...

    jboss4开发指南

    ### JBoss4开发指南知识点概览 #### 一、JBoss4.0.x概述 - **版本背景**:JBoss4.0.x是基于JBoss3.2.x开发而来,继承了后者在企业级应用中的稳定性,并在此基础上进行了功能增强和技术升级。 - **J2EE1.4认证**:...

    JBOSS开发人员指南

    通过命令行工具启动和停止JBoss服务,如使用`standalone.sh`或`domain.sh`脚本来控制单体模式和域模式的服务器实例。 三、应用部署 3.1 WAR与EAR文件 开发者通常将Java Web应用打包成WAR(Web ARchive)文件,而...

    JBoss管理与开发核心技术

    这本书以丰富的实例和详细的操作步骤,全面覆盖了JBoss的核心技术,旨在帮助读者掌握JBoss的配置、部署、监控以及性能优化等方面的知识。 JBoss,作为一个开源的应用服务器,是Java EE(现在称为Jakarta EE)平台的...

    JBoss4.0实例参考PDF格式

    6. **JMS(Java Message Service)**:JBoss 4.0内置了JMS支持,允许应用进行异步通信。文档可能包含如何配置消息队列和主题,以及发送和接收消息的方法。 7. **安全管理**:JBoss提供了角色基础的安全模型,包括...

    jboss开发文档

    JBoss 提供了丰富的服务,如JNDI(Java Naming and Directory Interface)、JMS(Java Message Service)、JTA(Java Transaction API)等。了解并掌握这些服务的使用方法,可以有效提升应用程序的性能和可扩展性。...

    Jboss EJB3.0 实例教程.pdf

    ### JBoss EJB3.0 实例教程知识点详解 #### 一、教程概览与适用人群 - **适用人群**:本教程适用于初学者及具有一定Java基础的学习者,特别是那些希望深入了解并掌握EJB 3.0技术的开发者。 - **内容特色**:通过...

    jboss 下载(httpwww.jboss.org)

    JBoss 是一个开源的、基于 J2EE(Java 2 Platform, Enterprise Edition)的应用服务器,由全球开发者社区共同维护和开发。它最初以 LGPL 许可协议发布,允许商业应用免费使用。2006年,JBoss 被著名的开源公司 Red ...

    JBoss管理与开发核心技术(第3版) English

    《JBoss管理与开发核心技术(第3版) English》是一本深入探讨JBoss应用服务器管理和开发的专业书籍。作为开源Java企业级应用服务器的先驱,JBoss在企业级Java应用程序的部署和管理方面扮演了重要角色。这本书针对...

    JBoss ESB新手指南

    JBoss ESB(Enterprise Service Bus)是Red Hat公司开发的一款开源服务总线,它提供了一种中间件解决方案,用于构建松散耦合、灵活且可扩展的企业级应用。作为新手入门,理解JBoss ESB的基本概念、功能以及如何操作...

Global site tag (gtag.js) - Google Analytics