政府机关 中间件jms

Spring JMS笔记

网上讲述Spring JMS的资料有两个版本,一个是onJava的jboss MQ版本,一个是ibm的IBM WebSphere MQ。本文使用jboss MQ为JMS Provider,并运行Spring JMS的例子,查看消息队列使用之前文章的Hermes.概述1) 什么是JMSJMS是Java API, 允许应用程序来建立、接收和读取消息。程序依靠这... 显示全部
网上讲述Spring JMS的资料有两个版本,一个是onJava的jboss MQ版本,一个是ibm的IBM WebSphere MQ。

本文使用jboss MQ为JMS Provider,并运行Spring JMS的例子,查看消息队列使用之前文章的Hermes.

概述
1) 什么是JMS
JMS是Java API, 允许应用程序来建立、接收和读取消息。程序依靠这些API, 在运行时需要一个JMS实现接口,来提供管理和控制,这被称为JMS provider, 现在有几种不同的JMS Provider; 在JBoss中的叫做JbossMQ。
2) JMS 和J2EE
JMS是在EJB和J2EE框架开发之前进行开发的,所以在JMS说明书中没有涉及到EJB或J2EE。
EJB 和J2EE第一代版本中也没有涉及到JMS,一直到EJB1.1,在生成一个可用Beand的容器provider中JMS也不是必须的API。在J2EE1.2中JMS接口是必需的情况,但并不是非得要包含一个JMS Provider;在EJB2.0和J2EE1.3中又进行改变,应用服务器包含了一个JMS Provider,自从J2EE1。3需要EJB2.0,增加了以下两个JMS特性:
w 一种新Bean类型定义, 也就是消息驱动Beam (MDB), 这种bean做为JMS消息监听者,可以异步地处理JMS消息。
w JMS处理作为资源,来自一个Bean 的JMD 发布(发送)必须能和其他bean的全局事务环境共享。这个需要把JMS认为是一个容器管理资源,象JDBC的连接。
3) JMS 和JBoss
JBoss从2.0版本以后都支持JMS。 在2.1中增加了MDB,从2.4版本开始JMS作为一个事务资源。
JBoss中JMS的体系结构如下:
JMS Provider, 叫做JbossMQ 。 是JBoss实现JMS 1.0.2规范的一部分,包括可选部分,象ASF(Application Service Facvility)。JbossMQ处理和普遍JMS一样:建立 queues (队列)或topic(标题),持久性等。 MDB (Message Driven Beans), 资源适配器。

JMS Provider
JBoss有它自己的JMS Provider 叫做JbossMQ。 适合与JMS 1.0.2 的JMS Provider,并且能用在所有平常的JMS程序中。为了清楚在JBoss中JMS是如何工作的,首先要清楚在JMS中涉及到的概念和术语,最好的办法是阅读JMS规范,下面给出了简单的JMS介绍。
1) JMS的简单介绍
当你发送一个消息,你不能直接发送到对此消息感兴趣的接受者。而是你发送到一个目的地。对此消息感兴趣的接受者必须连接到目的地,得到此消息或在目的地设置订阅。
在JMS中有两种域:topics 和queues 。
w 一个消息发送到一个topics ,可以有多个客户端。用topic发布允许一对多,或多对多通讯通道。消息的产生者被叫做publisher, 消息接受者叫做subscriber。
w queue 是另外一种方式,仅仅允许一个消息传送给一个客户。一个发送者将消息放在消息队列中,接受者从队列中抽取并得到消息,消息就会在队列中消失。第一个接受者抽取并得到消息后,其他人就不能在得到它。
为了能发送和接收消息,必须得到一个JMS连接。该连接是使用JMS Provider得到连接的,在得到连接之后,建立一个会话(Session)。然后再建立publisher/sender 来发送消息或subscriber/receiver来接收消息。
运行时,如果使用topic 那么publisher 或subscriber 通过一个topic来关联,如果使用queue ,则sender 或receiver通过queue来关联起来。
通常,在JMS框架中运转的方法如下:
(1) 得到一个JNDI初始化上下文(Context);
(2) 根据上下文来查找一个连接工厂TopicConnectFactory/ QueueConnectionFactory (有两种连接工厂,根据是topic/queue来使用相应的类型);
(3) 从连接工厂得到一个连接(Connect 有两种[TopicConnection/ QueueConnection]);
(4) 通过连接来建立一个会话(Session);
(5) 查找目的地(Topic/ Queue);
(6) 根据会话以及目的地来建立消息制造者(TopicPublisher/QueueSender)和消费者(TopicSubscriber/ QueueReceiver).
为了得到一个连接和得到一个目的地(用来关联publisher/sender 或subscriber/receiver),必须用provider-specific参数。
通过JNDI来查找相应的连接工厂或目的地,JNDI适合于任何JMS Provider。但是查找用的名字是provider使用的。因此,在你使用的JMS Provider(其中包括JBossMQ),必须学会如何进行指定。JMS Provider中的任何设置,象连接特性,用到目的地等,在用到的Provider都有明确描述。
2) 配置
当使用一个JMS Provider时,有三个Provider-specific因素:
得到一个JNDI初始化上下文
用到的连接工厂的名字。
对目的地的管理和命名协定。
JBoss同它的JNDI一起执行。为了简单的JMS client, 配置和查找初始化上下文,同实现其他J2EE客户端一样。
JMS-specific 来约束JBoss 的JMS provider (JBossMQ)。JbossMQ是通过xml 文件jbossmq-service.xml进行配置的,该文件放在在serverdefaultdeploy下。
在xml文件中最基本的三件事情:
增加一个新的目的地
配置用户
获得可用连接工厂的名字。
(1) 增加新的目的地
在目的地的xml文件在jboss 3.x中是jbossmq-destinations-service.xml(server/../deploy/jms)。在文件中已经存在几个缺省的目的地,所以你比较容易明白怎样增加到文件中。在例子中你需要一个topic目的地 spool,所以增加下面的语句到jbossmq-destinations-service.xml中。这种方式是长久存在的,不随着JBoss服务器关闭而消失。
name="jboss.mq.destination:service=Topic,name=spool">
jboss.mq:service=DestinationManager

另外一种方法是可以通过JMX HTML管理界面。通过http://localhost:8080/jmx-console 来访问。在jboss.mq 下查找service=DestinationManager 的连接。然后在createTopic()或createQueue()来建立,这种方法建立的目的地是临时性的,随着服务器开始存在,当当JBoss 服务器重新启动时,动态建立的目的地将会不存在。在JbossMQ中所有目的地都有一个目的地类型的前缀。对于topic前缀是topic ,对于queues前缀是queue。例如查找一个testTopic目的地,需要查找名字为“topic/testTopic”。
在此种方法中有createTopic()或createQueue()分别有两种方法:一是有两个参数,二是有一个参数的。两个参数分别是:建立的目的地名称和JNDI名称。一个参数的只是目的地名称,对于JNDI名称默认是:[目的地类型(topic/queue) ]/目的地名称。
在这里我们使用的是第一种方法。直接修改jbossmq-destinations-service.xml文件。
(2) 管理用户
在JMS中可能关联一个连接和一个用户,不幸的是没有明确的方法来限制访问JbossMQ或访问特殊的目的地到一个给定的用户。为了给大部分角色,在JbossMQ中不需要建立用户,除非想有一个持久topic订阅者。在这个例子中,用户是必须的。
用户可以直接在文件jbossmq-state.xml(server/../conf)中添加。同样也可以使用JMX HTML管理界面来增加
(3) 连接工厂
JBossMQ 包括为topic和queue几个不同的连接工厂,每个连接工厂有自己特性。当通过JNDI来查找一个连接工厂时,需要知道此连接工厂的名称。所有可用连接工厂和它们的属性,名称都会在文件jbossmq-service.xml中。
有三种类型连接工厂,依赖的通讯协议如下:
OIL
快速双向scoket通讯协议。它是缺省的。
UIL
超过一个socket协议,可以使用在通过防火墙访问,或者当客户端不能正确的查找到服务器的IP地址。
RMI
最早的协议,是稳定的,但是比较慢。
JVM
在JBoss 2.4之后增加的一个新的连接工厂类型。不需要用socket,当客户端和JbossMQ使用同样虚拟机时,可以使用。
在JBoss2.4.1以后版本中,对于topic- 和 queue-目的地,连接工厂使用同样的名字。下表列出了在JBoss中JMS连接工厂:
目的地类型 JNDI名字 连接工厂类型
Topic/Queue java:/ConnectionFactory JVM
Topic/Queue java:/XAConnectionFactory JVM支持XA事务
Topic/Queue RMIConnectionFactory RMI
Topic/Queue RMIXAConnectionFactory RMI支持XA事务
Topic/Queue ConnectionFactory OIL
Topic/Queue XAConnectionFactory OIL支持XA事务
Topic/Queue UILConnectionFactory UIL
Topic/Queue UILXAConnectionFactory UIL支持XA事务

  

异步进程通信是面向服务架构(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代码中重新抛出。

一旦您在JMS应用程序中开始使用Spring,您将会欣赏到它在处理异步消息传递上的简便。Spring JMS框架提供多种Java类,可以轻松实现JMS应用。 收起
参与6

查看其它 4 个回答xiaoguizi 的回答

xiaoguizi xiaoguizi 系统工程师 普元科技有限公司
学习了。。。
金融其它 · 2012-03-23
浏览1069

回答者

xiaoguizi
系统工程师 普元科技有限公司
评论126

xiaoguizi 最近回答过的问题

回答状态

  • 发布时间:2012-03-23
  • 关注会员:1 人
  • 回答浏览:1069
  • X社区推广