用Spring JMS使异步消息变得简单.doc_第1页
用Spring JMS使异步消息变得简单.doc_第2页
用Spring JMS使异步消息变得简单.doc_第3页
用Spring JMS使异步消息变得简单.doc_第4页
用Spring JMS使异步消息变得简单.doc_第5页
已阅读5页,还剩9页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

用Spring JMS使异步消息变得简单异步处理通信是面向服务架构(SOA)的重要部分,因为企业中的许多系统通信,尤其是跟外部系统通信本来就是异步的。Java消息服务(JMS)就是用来编写异步消息J2EE应用的API。使用JMS API的传统消息实现涉及到象这样的一些步骤:查找对列连接工厂、队列资源以及在实际发送和接受消息前,创建JMS会话(JMS session)。Spring framework简化了用JEE组件(包括JMS)开发JMS应用的工作。它提供了一个模板机制来隐藏典型的JMS实现细节,所以开发者可以专注于消息处理任务而不用担心怎样创建、访问和释放JMS资源。本文用一个运行在JBoss MQ server上的简单Web应用概述了Spring JMS API和怎样使用它异步处理(发送和接受)消息。我将对比JMS实现的传统方法和Spring JMS实现方法,以显示使用Spring JMS来处理消息是多么的简单和灵活。异步消息和SOA现实世界中,大多数Web请求是同步处理的。例如,当用户登陆一个站点,他或她输入用户名和口令以及服务器识别登陆凭证。如果身份验证成功,程序让用户进入站点。这里,登陆请求从客户端被接受后,立即被处理。信用卡授权也是一个同步处理的例子;仅当服务器核实了发送进来的信用卡号是有效并且该客户的帐号有足够的信用额度后,才允许客户继续进行下一步动作。让我们来考察一下订单处理系统中的支付结算步骤。一旦系统核实了那个用户的信用卡信息是正确的,而且帐户上有足够的资金,那么不需要等到支付细节和转帐最终完成。支付结算用异步方式处理,如此客户便可以继续进行结帐处理。与典型的同步请求相比,异步处理用于需要长时间来处理的请求。异步处理的另外一个例子是住房贷款处理应用中,处理提交到AUS(Automated Underwriting System)的贷款请求。贷款人提交贷款申请后,抵押公司发送请求到AUS取得信用历史信息。因为该请求要取得综合详细的信用报告如贷款人当前和过去的信用帐户,最近的支付以及其它金融详细信息,所以从请求到获得响应常常需要很长时间。对客户端程序来说开一个到服务器的连接并且长时间等待响应是没有意义的。于是就有了异步通信;也就是,一旦请求被提交,它就被放入队列里面并且客户断开服务器连接。然后,AUS服务从特定队列摘取请求,处理它,把结果消息放入另外一个消息队列。最后客户程序从消息队列摘取响应结果继续处理信用历史结果信息。JMS如果用过JMS的话,会发现它类似写JDBC或JCA代码。它有创建或检索JMS资源的样板代码,每当你需要编写一个新类来发送或接受消息时,都得重复编写那个样本代码。下面列出了传统JMS实现涉及的步骤:1、创建JNDI初始上下文context;2、从JNDI上下文获得队列连接工厂;3、从队列连接工厂取得队列Queue;4、创建一个Session对象;5、创建一个发送或接受对象;6、利用第5部创建的发送或接受对象发送或接受消息;7、处理完消息后,关闭所有JMS资源。如你所见,只有第6步是处理消息的步骤。其他步骤都只是管理JMS资源,与实际业务需求无关,但开发者不得不编写和维护那些附加步骤代码。Spring JMSSpring框架提供一个模板机制来隐藏Java API细节。JEE开发者可用JDBCTemplate 和JNDITemplate类来分别访问后端数据库和JEE资源(数据源,连接池)。JMS没有异常。Spring提供了JMSTemplate类,所以开发者不必为JMS实现编写样本代码。当开发JMS应用时,Spring提供了一下一些优势:1、提供了一个JMS的抽象API,简化了JMS的使用。如:访问目的地(队列或主体)和出版消息到特定目的地。2、JEE开发者不必关心JMS不同版本之间的差异(如JMS 1.0.2 同 JMS 1.1);3、开发者不必特定地处理JMS异常,因为Spring为JMS代码抛出的任何JMS异常提供了一个unchecked异常。一旦你在JMS应用中开始使用Spring,你将会欣赏到异步消息处理的简易性。Spring JMS框架提供了各种java类使JMS开发变得简单。表1,Spring JMS类随后的部分,我将详细解释表1中的类(如JmsTemplate, DestinationResolver,和 MessageConverter)。JMSTemplateJmsTemplate提供了几个helper方法来执行基本操作。开始使用JmsTemplate前,有必要知道JMS提供者支持哪种JMS规范。JBoss AS 4.0.2 和 WebLogic 8.1服务器支持JMS1.0.2规范。WebLogic 服务器 9.0包含JMS1.1支持。JMS1.1统一了PTP和Pub/Sub编程接口。有了这个改变,开发者可以创建一个事务会话,然后在同一个JMS事务中,从Queue(PTP)接受消息和发送一个消息到Topic(Pub/Sub)。JMS1.1向后兼容JMS1.0,因此基于JMS1.0编写的代码仍然能跟JMS1.1工作。JmsTemplate提供各种方法来接收和发送消息。表2是方法列表。表2。JMS模板方法使用JNDI上下文存储和检索目的地。当配置Spring应用上下文时,我们用JndiObjectFactoryBean获得JMS目的地引用。DestinationResolver用来解析目的地名称到一个JMS目的地,当应用有许多目的地时,那是很有帮助的。DynamicDestinationResolver(缺省DestinationResolver实现)用于解析动态目的地。MessageConverter接口定义了java对象和JMS消息之间转换的契约。使用转换器,应用代码可以专注于业务对象,不用操心它是如何代表JMS消息的。SimpleMessageConverter(和SimpleMessageConverter102)是缺省MessageConverter实现。它们用于将String、字节数组((byte)、Map、Serializable对象分别转换成JMS TextMessage、JMS BytesMessage,JMS MapMessage,JMS ObjectMessage。你可以编写MessageConverter接口的定制实现并结合XML绑定框架如JAXB, Castor, Commons Digester, XMLBeans, 或 XStream来转换XML文档到TextMessage。样本应用我将用一个样本贷款应用处理系统(叫LoanProc)来说明怎样在JMS应用中使用Spring。作为贷款处理的一部分,LoanProc发送贷款详细资料(loan ID, borrower name, borrowers SSN, loan expiration date, and loan amount)从AUS系统请求信贷历史。为让例子简单一点,我们将基于两个参数:信用评分和贷款数量来获得信贷历史详细资料。让我们假定处理信用检查请求的业务规则如下:1、如果贷款数量等于或小于$500,000,那么贷款人必须至少有一个“good”信用(例如,贷款人的信用评分在680到699之间);2、如果贷款数量超过$500,000,那么贷款人必须至少要有一个“very good”信用,这意味他/她的信用评分超过700。贷款应用Use Case贷款请求处理Use Case由下列步骤组成:1、用户在贷款申请web页面输入贷款详细资料并提交贷款申请;2、然后程序发送贷款详细资料到AUS系统取得信用历史详细资料。用发送请求到名叫CreditRequestSendQueue的消息队列来完成。3、AUS系统从队列摘取贷款详细资料并用贷款参数来从数据库检索信用历史信息;4、然后AUS系统用找到的贷款人信用历史信息创建一个新的消息并发送到名叫CreditRequestReceiveQueue的消息队列;5、最后LoanProc从接收消息队列摘取响应消息并处理贷款申请,决定申请是被核准还是拒绝。应用中,在同样的JBoss MQ server中配置了两个消息队列。Use Case用序列图1表示如下:图1:贷款处理应用的序列图技术表3列出了例子应用中用到的一些技术和开源框架表3,JMS应用中用到的框架使用Hermes 的JMS资源设置为异步处理消息,首先,我们需要消息队列来发送和接收消息。我们在JBoss中使用xml配置文件创建消息队列并且用JMS控制台来浏览队列详细资料。清单1显示了XML配置文件JMS配置片断。(这个片断可以被添加到%JBOSS_HOME%serveralldeploy-hasingletonjms目录下的jbossmq-destinations-service.xml文件中。)清单1,JBoss MQ服务器中JMS队列配置!- Credit Request Send Queue -mbean code=org.jboss.mq.server.jmx.Queue name=jboss.mq.destination:service=Queue,name=CreditRequestSendQueue depends optional-attribute-name=DestinationManager jboss.mq:service=DestinationManager /depends/mbean!- Credit Request Receive Queue -mbean code=org.jboss.mq.server.jmx.Queue name=jboss.mq.destination:service=Queue,name=CreditRequestReceiveQueue depends optional-attribute-name=DestinationManager jboss.mq:service=DestinationManager /depends/mbean现在,让我们看看怎么使用一个叫做Hermes的JMS工具浏览消息队列。Hermes是一个Java Swing应用,它能创建、管理和监控JMS提供者中的JMS destination。这样的JMS提供者有JBossMQ, WebSphereMQ, ActiveMQ 和 Arjuna。从website下载Hermes并解压zip文件到一个本地目录(如c:devtoolshermes)。一旦安装,双击hermes.bat (在bin目录)启动程序。为在Hermes中配置JBossMQ服务器,参考Hermes站点上的demo。它一步一步形象说明了JBoss MQ的配置。当配置一个新的JNDI初始上下文时,输入下面的配置信息。providerURL = jnp:/localhost:1099 initialContextFactory = erfaces.NamingContextFactory urlPkgPrefixes = erfaces:org.jboss.naming securityCredentials = admin securityPrincipal = admin 当创建一个新destinations时,输入queue/CreditRequestSendQueue 和 queue/CreditRequestReceiveQueue。图2显示了JMS控制台主屏幕,它显示了为样本JMS应用创建的新消息。图2.Hermes中所有destinations的截屏图3是消息发送者发送一些消息到CreditRequestSendQueue后,Hermes JMS控制台显示的消息队列详细资料。你能看到这里队列中有5个消息并且控制台显示了消息的详细信息如message ID、message destination、time stamp、和实际的消息。图3.Hermes中队列详细资料截屏使用Spring JMS,异步消息变得简单用在样本应用中的这些消息队列名和其它JMS以及JNDI参数如下表4所示。表4,Spring JMS配置参数Spring配置已经有了运行样本应用所需的JMS destinations,现在该是进入用XML Spring配置文件(叫做spring-jms.xml)装配JMS组件的细节的时候了。用IOC设计模式中的setter依赖注入原理装入这些组件。让我们仔细看看组件,为每一个JMS组件显示了一个XML配置片断。JNDI上下文是获取JMS资源的入口,所以我们首先配置一个JNDI模板。清单2显示了一名为jndiTemplate的Spring bean,它具有取得JNDI初始上下文必须的常用参数。清单2,JNDI上下文模板 erfaces.NamingContextFactory localhost erfaces:org.jboss.naming 下一步,我们配置队列连接工厂。清单3显示了队列连接工厂。清单3,JMS对了连接工厂配置 UIL2ConnectionFactory 我们定义了两个JMS destinations来发送和接收消息。清单4和清单5显示了这些细节。清单4,发送队列配置 queue/CreditRequestSendQueue 清单5,接收队列配置 queue/CreditReqeustReceiveQueue 然后,我们配置JmsTemplate组件。我们在样本应用中使用JmsTemplate102。使用defaultDestination属性来指定JMS destination。清单6,JMS template配置 30000 最后,我们配置发送和接收者组件。清单7和清单8显示了Sender 和Receiver 对象配置。清单7,JMS Sender配置Listing 7. JMS Sender configuration 清单8,JMS Receiver配置 测试和监控我些了一个叫做LoanApplicationControllerTest的测试类来测试LoanProc应用。我们使用这个类来设置贷款参数和调用那个信用请求服务类。让我们看看使用传统JMS而不用Spring JMS API的消息发送者实现。清单9显示了MessageSenderJMS这个类的sendMessage方法,这个类具备使用JMS API处理消息的所有必须步骤。清单9,传统JMS实现public void sendMessage() queueName = queue/CreditRequestSendQueue; System.out.println(Queue name is + queueName); /* * Create JNDI Initial Context */ try Hashtable env = new Hashtable(); env.put(java.naming.factory.initial, erfaces.NamingContextFactory); env.put(vider.url,localhost); env.put(java.naming.factory.url.pkgs, erfaces:org.jboss.naming); jndiContext = new InitialContext(env); catch (NamingException e) System.out.println(Could not create JNDI API + context: + e.toString(); /* * Get queue connection factory and queue objects from JNDI context. */ try queueConnectionFactory = (QueueConnectionFactory) jndiContext.lookup(UIL2ConnectionFactory); queue = (Queue) jndiContext.lookup(queueName); catch (NamingException e) System.out.println(JNDI API lookup failed: + e.toString(); /* * Create connection, session, sender objects. * Send the message. * Cleanup JMS connection. */ try queueConnection = queueConnectionFactory.createQueueConnection(); queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); queueSender = queueSession.createSender(queue); message = queueSession.createTextMessage(); message.setText(This is a sample JMS message.); System.out.println(Sending message: + message.getText(); queueSender.send(message); catch (JMSException e) System.out.println(Exception occurred: + e.toString(); finally if (que

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论