近期由于工作需要,接触了一下MQ,在此记录学习笔记.
与JDBC API for databases 一样,Java Message Services(JMS)是消息发送的标准API。
JMS 规范(1.0.2)由Sun Microsystems 开发,IBM 和其他企业消息发送销售商、事务处
理销售商以及RDBMS 销售商都积极参与了开发过程。
JMS 具有两种消息发送风格,或者说它具有两个域: 一对一或点到点模型. 发布/预订模型.
但是,JMS 仅仅是种规范。每个企业消息发送系统销售商都必须就其特定的消息发送系统提供
实施规范的类。
为什么要使用 JMS?JMS 标准非常重要,其原因在于:
它是第一个获取广泛跨行业支持的企业消息发送API;
它提供的标准消息发送概念和惯例适用于广泛的企业消息发送系统,因而简化了企业应用程序的开发;
它可以利用现有的、企业证明成功可行的消息发送系统;
它添加了完全用现有非JMS 客户机解释的新JMS 客户机,从而允许您扩展现有的基于消息的应用程序;
它允许您可以编写便携性强的基于消息的商业应用程序。
连接
连接提供了到底层传输的访问,并被用来创建会话。在 MQSeries 上下文中,连接提供
了储存参数,如队列管理器名、远程主机名(在Java 客户连接性中)等的地方。换言之,
MQSeries JMS 连接一般都在Java 虚拟机之外分配MQSeries 资源。连接也支持同时使用。
JMS 客户机一般创建一个连接 、一个或多个会话以及许多消息生成器和使用者。当创建
连接时,它处在停止模式,这就是说没有消息再被送达。
重点:连接是在停止模式中创建的。(默认为停止模式)
通常,直到设置完成前,连接都处在停止模式中。在完成时,将调用连接的start()方
法,而消息则开始到达连接的使用者。
提示:消息生成器可以在停止连接时发送消息。
就PTP(P2P) 连接而言,我们利用QueueConnectionFactory 或XAQueueConnectionFactory
来获取QueueConnection 或XAQueueConnection
就发布/ 预订 消息发送模式而言, 我们利用TopicConnectionFactory 或
XATopicConnectionFactory 来获取TopicConnection 或XATopicConnection。
@@为了创建连接,我们应当进行以工作:
为了从JNDI 名称空间接收对象,必须按照下面这段代码所显示的那样设置初始上
import javax.jms.* import javax.naming.*; import javax.naming.directory.*; java.util.Hashtable ; Hashtable env =new Hashtable(); env.put(Context.INITIAL_CCONTEXT_FACTORY,icf); env.put(Context.PROVIDER_URL,url); Context ctx =new InitialDirContext(env);
Icf 为初始上下文定义了库类,url 则定义了随上下文而变的URL。
QueueConnectionFactory qFactory ; queueFactory =(QueueConnectionFactory)ctx.lookup(“cn=firstQCF ”);
QueueConnection connection ; connection =qFactory.createQueueConnection();
JMS 规范定义指出,应当在“停止”状态下创建连接。在您可以利用连接发送消息
之前,必须显式启动连接。
我们利用 start()方法启动连接,请参见如下的例子:
connection.start();
会话
为生成和使用消息提供上下文,包括用来创建消息生成器和消息使用者的方法。
JMS 会话是生成和使用消息的单线程上下文。尽管它可以在Java 虚拟机之外分配供应
方资源,但我们还是将其看作轻量级JMS 对象。
我们可以分别利用连接对象的 createQueueSession()或createTopicSession()方法来创
建会话。
创建会话方法包括两个参数:
1. 可决定会话是否进行事务处理的boolean。
在事务处理的会话中,全部发送、或者全部接收作为一个单位的一组消息。
在非事务处理会话中,分别发送或接收消息。
2. 定义识别模式的参数。
请参见如下的例子:
session =connection.createQueueSession(false ,Session.AUTO_ACKNOWLEDGE);
这是用 AUTO_ACKNOWLEDGE 来创建非事务处理会话的最简单的情况。连接是
线程安全的,但会话和由会话创建的对象不是线程安全的。我们建议多线程应用程
序应当对每个线程都使用不同的会话。
会话有以下几种用途:
它是消息生成器和使用者的库;
它提供了供应方优化的消息库;
它既支持单一事务处理,又支持一系列将跨越生成器和使用者的库结合到原子单位的事务处理;
会话为它使用和生成的消息定义了连续序列;会话保存了它使用的消息,直到识别该消息;
会话串行化注册到消息使用者的消息侦听器。
会话可以创建并服务于多个消息生成器和使用者。
我们可以选择地指定会话为事务处理会话。每个事务处理会话都支持单一系列的事务处
理。每个事务处理会将一系列消息发送和一系列消息接收归组到原子库单元中。事实上,
事务处理将会话的输入消息流和输出消息流组织到原子单位集中。当提交事务处理时,
会确认输入的原子单位,同时发送与其相关联的输出原子单位。如果已经进行了事务处
理回退,那么其发送的消息则被毁坏,会话的输入也被自动恢复。
我们可以利用会话的提交或回退方法完成事务处理。会话的当前事务处理的完成将自动
开始下一个事务处理。其结果就是,事务处理会话总是具有一个当前事务处理,且其库
就在当前事务处理中完成。
消息生成器
JMS 客户机利用消息生成器发送消息到特定的目的地。我们通过传递目的地到会话对象
提供的创建消息生成器方法,从而创建消息生成器。
在点到点消息发送中,这将是利用 QueueSession 对象上的createSender 方法所创建的
QueueSender。QueueSender 通常是为特定队列创建的,因此所有利用该发送器发送的消
息都会被发送到同样的目的地。我们利用队列对象指定目的地。队列对象即可以在运行
时间中创建,也可以在JNDI 名称空间中构造和储存。请参见如下的例子:
Queue ioQueue ; ioQueue = (Queue).ctx.lookup(qLookUp) ; sender = session.createSender(ioQueue);
在发布/预订消息发送中,这将是在 TopicSession 对象上利用createPublisher 方法创建
的TopicPublisher。
通常,Topic 是在创建TopicPublisher 时指定的。在这种情况下,尝试去使用方法,该方
法为未确认的TopicPublisher,将生成UnsupportedOperationException。
Topic topic ; topic = (Topic)ctx.lookup( “cn=first.topic”) ; TopicPublisher pub = session.createPublisher(topic);
客户机可以通过消息生成器为发送的消息指定默认的送达模式、优先级和使用期限。它
也可以为每条消息指定送达模式、优先级和使用期限。
发送消息
消息是用消息生成器发送的。因此在点到点(PTP)模型中发送消息时,您应当使用
QueueSender 对象,而在发布/预订模型中,您则应当使用TopicPublisher 对象。
在 PTP 模型中,应使用QueueSender 的send()方法发送消息。请参见如下的例子:
outmessage = session.createTextMessage(); outmessage.setText(“Sample Message “) ; sender.send(outMessage);
在发布/预订模型中,应使用 TopicPublisher 对象的发布方法来发布消息。请参见如下的例子:
pub.publish(outMessage);