`
sunwei_1002
  • 浏览: 12053 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

用Spring快速开发jms应用(JBOSS服务器)

阅读更多
核心提示:异步进程通信是面向服务架构(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文件,加入以下代码片断:

<!--  Register User Send/Receive Queue  --> 
<mbean code="org.jboss.mq.server.jmx.Queue" 
  name="jboss.mq.destination:service=Queue,name=registerUserQueue"> 
  <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> 
</mbean> 
<!--  Register User Send/Receive Topic  --> 
<mbean code="org.jboss.mq.server.jmx.Topic" 
name="jboss.mq.destination:service=Topic,name=registerUserTopic"> 
  <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> 
</mbean> 

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

<!-- JNDI上下文(它是取得JMS资源的起始位置) --> 
bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"> 
<property name="environment"> 
<props> 
  <prop key="java.naming.factory.initial"> 
   org.jnp.interfaces.NamingContextFactory  
  </prop> 
  <prop key="java.naming.provider.url">localhost</prop> 
  <prop key="java.naming.factory.url.pkgs"> 
   org.jnp.interfaces:org.jboss.naming  
  </prop> 
</props> 
</property> 
/bean> 

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

<!-- JMS连接工厂 --> 
  <bean id="jmsConnectionFactory"class="org.springframework.jndi.JndiObjectFactoryBean"> 
<property name="jndiTemplate"> 
  <ref bean="jndiTemplate" /> 
</property> 
<property name="jndiName"> 
  <value>XAConnectionFactory</value> 
</property> 
</bean> 

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

<!-- JMS模板配置 --> 
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate102"> 
<property name="connectionFactory" ref="jmsConnectionFactory" /> 
<property name="defaultDestination" ref="destination" /> 
<property name="pubSubDomain"> 
  <value>true</value> 
</property> 
<!-- 等待消息的时间(ms) --> 
<property name="receiveTimeout"> 
       <value>30000</value> 
    </property> 
</bean> 

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

<bean id="destination" class="org.springframework.jndi.JndiObjectFactoryBean"> 
<property name="jndiTemplate"> 
  <ref bean="jndiTemplate" /> 
</property> 
<property name="jndiName"> 
  <value>topic/registerUserTopic</value> 
</property> 
</bean> 

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

<!-- 消息发布者 --> 
<bean id="msgProducer" class="com.boco.jms.MessageProducer"> 
<property name="jmsTemplate" ref="jmsTemplate" /> 
</bean> 
<!-- 消息接收者 --> 
<bean id="msgConsumer" class="com.boco.jms.MessageConsumer"> 
<property name="jmsTemplate" ref="jmsTemplate" /> 
</bean> 

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

/** 
*  User.java 
*  created on Jul 2, 2006 
*  Copyrights 2006 BOCO,Inc. All rights reserved. 
*/ 
package com.boco.dto;  
 
import java.io.Serializable;  
 
/** 
* desc: 用户信息 Bean 
* @author qiujy 
*/ 
public class User {  
private int id;  
private String username;  
private String password;  
private String email;  
   
public User(){}  
   
//以下为Getter,setter方法略  
......  


 
(2).消息生产者:

/** 
*  MessageProducer.java 
*  created on Jul 22, 2006 
*  Copyrights 2006 BOCO,Inc. All rights reserved. 
*/ 
package com.boco.jms;  
 
import javax.jms.JMSException;  
import javax.jms.MapMessage;  
import javax.jms.Message;  
import javax.jms.Session;  
 
import org.springframework.jms.core.JmsTemplate;  
import org.springframework.jms.core.MessageCreator;  
 
import com.boco.dto.User;  
 
/** 
* desc:消息生产者 
* @author qiujy 

*/ 
public class MessageProducer {  
/** JMS模板 */ 
private JmsTemplate jmsTemplate;  
   
public void setJmsTemplate(JmsTemplate jmsTemplate){  
  this.jmsTemplate = jmsTemplate;  
}  
   
public void sendMessage(final User user){  
  //调用模板的send来发送消息  
  jmsTemplate.send(new MessageCreator(){  
 
   public Message createMessage(Session session) throws JMSException {  
    //构造一个要发送的消息  
    MapMessage message = session.createMapMessage();  
     message.setInt("id", user.getId());  
     message.setString("username", user.getUsername());  
     message.setString("password", user.getPassword());  
     message.setString("email", user.getEmail());  
    System.out.println("send success!!");  
    return message;  
   }  
  });  
}  
}  
 
(3).消息消费者:

/** 
*  MessageConsumer.java 
*  created on Jul 22, 2006 
*  Copyrights 2006 BOCO,Inc. All rights reserved. 
*/ 
package com.boco.jms;  
 
import javax.jms.JMSException;  
import javax.jms.MapMessage;  
 
import org.springframework.jms.core.JmsTemplate;  
 
import com.boco.dto.User;  
 
/** 
* desc:消息消费者 
* @author qiujy 

*/ 
public class MessageConsumer {  
/** JMS模板 */ 
private JmsTemplate jmsTemplate;  
   
public void setJmsTemplate(JmsTemplate jmsTemplate){  
  this.jmsTemplate = jmsTemplate;  
}  
   
public User receiveMessage(){  
  //参数为Destination的JNDI名字去掉前面的模式类型标识  
  //MapMessage msg = (MapMessage)jmsTemplate.receive("registerUserQueue");  
  MapMessage msg = (MapMessage)jmsTemplate.receive("registerUserTopic");  
  User user = new User();  
    
  try {  
   user.setId(msg.getInt("id"));  
   user.setUsername(msg.getString("username"));  
   user.setPassword(msg.getString("password"));  
   user.setEmail(msg.getString("email"));  
  } catch (JMSException e) {  
   // TODO Auto-generated catch block  
   e.printStackTrace();  
  }  
    
  return user;  
}  

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

/** 
*  TestMsgProducer.java 
*  created on Jul 22, 2006 
*  Copyrights 2006 BOCO,Inc. All rights reserved. 
*/ 
package com.boco.jms;  
 
import junit.framework.TestCase;  
 
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
 
import com.boco.dto.User;  
 
/** 
* desc: 
* @author qiujy 

*/ 
public class TestMsgProducer extends TestCase {  
 
private ApplicationContext context;  
/** 
  * @param arg0 
  */ 
public TestMsgProducer(String arg0) {  
  super(arg0);  
  context = new ClassPathXmlApplicationContext("applicationContext_jms.xml");  
}  
 
/* (non-Javadoc) 
  * @see junit.framework.TestCase#setUp() 
  */ 
protected void setUp() throws Exception {  
  super.setUp();  
}  
 
/* (non-Javadoc) 
  * @see junit.framework.TestCase#tearDown() 
  */ 
protected void tearDown() throws Exception {  
  super.tearDown();  
}  
 
/** 
  * Test method for {@link com.boco.jms.MessageProducer#sendMessage(com.boco.dto.User)}. 
  */ 
public void testSendMessage() {  
  User user = new User();  
  user.setId(132);  
  user.setUsername("JMSTest");  
  user.setPassword("password");  
  user.setEmail("support@boco.com.cn");  
    
  MessageProducer producer = (MessageProducer)context.getBean("msgProducer");  
    
  producer.sendMessage(user);  
    
}  
 

//============ 消费者测试用例 ===============  
/** 
*  TestMsgConsumer.java 
*  created on Jul 22, 2006 
*  Copyrights 2006 BOCO,Inc. All rights reserved. 
*/ 
package com.boco.jms;  
 
import junit.framework.TestCase;  
 
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
 
import com.boco.dto.User;  
 
/** 
* desc: 
* @author qiujy 

*/ 
public class TestMsgConsumer extends TestCase {  
private ApplicationContext context;  
/** 
  * @param arg0 
  */ 
public TestMsgConsumer(String arg0) {  
  super(arg0);  
  context = new ClassPathXmlApplicationContext("applicationContext_jms.xml");  
}  
 
/* (non-Javadoc) 
  * @see junit.framework.TestCase#setUp() 
  */ 
protected void setUp() throws Exception {  
  super.setUp();  
}  
 
/* (non-Javadoc) 
  * @see junit.framework.TestCase#tearDown() 
  */ 
protected void tearDown() throws Exception {  
  super.tearDown();  
}  
 
/** 
  * Test method for {@link com.boco.jms.MessageConsumer#receiveMessage()}. 
  */ 
public void testReceiveMessage() {  
  MessageConsumer consumer = (MessageConsumer)context.getBean("msgConsumer");  
  User user = consumer.receiveMessage();  
  assertNotNull(user);  
  System.out.println( "id========" + user.getId()  
      + "\nname======" + user.getUsername()  
      + "\npassword==" + user.getPassword()  
      + "\nemail=====" + user.getEmail());  
}  
 
}

我觉得写的不错,很有参考价值。 
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liuzhenwen/archive/2009/01/13/3768766.aspx
分享到:
评论

相关推荐

    jboss服务器下的jms实例

    总的来说,使用Spring JMS在JBoss服务器上实现JMS通信,不仅提高了代码的可读性和可维护性,还降低了开发复杂性,使得开发者能更专注于业务逻辑,而不是底层的JMS实现。这对于构建高效、健壮的企业级服务是非常有利...

    spring-jboss整合

    而JBOSS作为一款广泛使用的开源应用服务器,提供了丰富的服务和功能,能够满足复杂的企业级应用需求。因此,如何将Spring框架与JBOSS应用服务器进行有效的整合,成为了许多开发者关注的重点。 #### 二、Spring与...

    JBOSS服务器压缩包

    JBoss 服务器,全称为 JBoss Application Server,是 Red Hat 公司开发的一款开源的企业级 Java 应用服务器,它基于Java EE(Java Enterprise Edition)规范,提供了对Web应用程序和企业级服务的支持。作为Java...

    基于Jboss的jms编程

    【基于Jboss的JMS编程】是关于Java消息服务(JMS)在Jboss应用服务器上的实现和配置的教程,适合初学者理解JMS的基本概念和应用。JMS是一种标准API,用于在分布式环境中发送、接收和管理消息,提供可靠的数据传输。 ...

    使用Eclipse开发J2EE应用.rar_eclipse j2_eclipsej2_jboss_lomboz

    在本文中,我们将深入探讨如何使用Eclipse IDE进行J2EE应用程序的开发,结合Lomboz插件和JBoss应用服务器。...在实践中不断探索和磨练,你将能驾驭这一强大的开发平台,实现高质量的J2EE应用开发。

    JMS相关的Source

    在这个"JMS相关的Source"中,我们可以看到是关于JMS与JBoss应用服务器以及Spring框架集成的代码示例。 首先,JBoss是一个开源的应用服务器,它支持多种Java EE规范,包括JMS。在Jboss中,JMS服务通常通过 HornetQ ...

    JBOSS+TOMCAT集成开发环境。完整版

    【JBOSS+TOMCAT集成开发环境】是一种常见的企业级应用服务器组合,它结合了JBOSS的全面中间件服务和TOMCAT的轻量级Servlet容器特性,为开发者提供了一个高效且灵活的开发与部署平台。在这个“完整版”中,用户可以...

    JBoss开发实践指南

    JBoss是基于Java的开源应用服务器,它提供了全面的Java EE(企业版)支持,包括Web服务、EJB(Enterprise JavaBeans)、JMS(Java消息服务)等关键组件,是企业级应用开发的重要平台。 本书首先介绍了JBoss的基础...

    windows下JBOSS5.1.0部署web应用

    完成以上步骤后,JBOSS服务器应该能够根据你的需求运行Web应用,并支持SSL安全连接。在实际操作中,可能还需要根据具体的应用需求调整其他配置,如数据源、JMS队列等。务必仔细检查所有配置文件,确保没有语法错误,...

    Jboss开发者手册

    《JBoss开发者手册》是专为Java开发人员提供的一份详尽指南,它涵盖了JBoss应用服务器的各个方面,包括安装、配置、管理以及应用程序的开发和部署。JBoss是一款开源的Java EE应用服务器,它提供了全面的支持来实现...

    Spring JMS 消息处理-基于JNDI

    在IT行业中,Spring框架是Java开发中的重要工具,它提供了丰富的功能来简化应用程序的构建,尤其是在企业级应用中。Spring JMS(Java消息服务)模块是Spring框架的一部分,用于处理消息队列通信,这是一种异步处理和...

    JBoss管理与开发核心技术

    3. **部署应用**:理解WAR、EAR和JAR文件格式,学习如何将Java EE应用部署到JBoss服务器,包括使用管理控制台或命令行工具进行部署。 4. **安全管理**:掌握JBoss的安全机制,如用户角色、认证和授权,以及如何设置...

    Jboss4.2.2+Spring2.5.6+hibernate+JTA事务的实现

    **JBoss 4.2.2** 是一个流行的开源Java应用服务器,它提供了运行和管理Java EE应用程序的平台。这个版本支持EJB 3.0,JPA,JMS等标准,为开发者提供了容器化的部署环境和管理工具。 **Spring 2.5.6** 是一个轻量级...

    IBM MQ与JBOSS整合,通过SPRING来读写消息

    1. **配置IBM MQ**:在JBoss服务器上安装IBM MQ的JMS客户端库,这些库包含所需的驱动程序和API,使得JBoss能够连接到MQ服务器。确保配置正确的MQ连接参数,如主机名、端口、队列管理器名称以及通道。 2. **创建JNDI...

    jboss,java,eclipse,flex

    JBoss支持各种服务,如Servlets、JSP、EJB、JMS、JPA等,并且与Spring框架和Hibernate ORM紧密集成。JBoss的使用使得开发者可以快速地开发出可扩展、高性能和安全的Web应用。 【Java】 Java是一种广泛使用的面向...

    jboss资料大全,内容丰富,搜之不易

    JBoss,全称为Red Hat JBoss,是Red Hat公司推出的一款开源的应用服务器,它基于Java EE(Java Platform, Enterprise Edition)规范,为开发和部署企业级应用提供了强大的平台支持。本资料大全涵盖了JBoss的各个方面...

    ESB应用Spring_Hello_World

    总结,这个ESB应用Spring_Hello_World实例是学习和理解如何在JBoss ESB中整合Spring框架进行服务开发的一个基础练习。通过这个示例,开发者可以了解到ESB中的消息传递机制、队列配置以及如何利用Spring进行服务实现...

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

    《JBoss+jBPM+jPDL用户开发手册_3.2.3》是针对企业级应用开发的一个详尽指南,特别关注于工作流管理和流程自动化。这个手册详细介绍了如何使用JBoss中间件平台,结合jBPM(Java Business Process Management)和jPDL...

Global site tag (gtag.js) - Google Analytics