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

初识 JMS

    博客分类:
  • jms
 
阅读更多

自己搞了J2EE这么久,EJB/JNDI/RMI/JTA这些都了解的七七八八。但是,对于JMS这个东东,只听说在EJB的消息 bean中有用到过, 一直以来俺都敬而远之。最近公司要做一个国外的外包项目,里头有涉及到JMS的技术,现在只能临时抱佛脚。互联网上关于JMS的文章少之又少,没办法,只有自力更生,硬是查看了SUN的官方技术API文档,也算是初步揭开JMS这个神秘的面纱吧。

JMS的基本概念

JMS(Java Message Service) 的主要目的是为了在我们的Java程序之间用分布式的方式实现对消息的创建、发送、接收和读取。一个典型的JMS应用,主要包含以下几个部分:
●JMS Provider -- JMS的核心模块,用来控制和管理JMS应用。如果说JMS整个是一个十字路口,那么这个Provider应该就充当交通信号灯和
交警的角色了。
●JMS Clients -- 接收和发送message的Java程序终端,简单的说应该就是交互的源/目标对象,可以有一个或多个Clients存在。
●Messages -- 在JMS Clients中间传递交互的消息对象,这是JMS最基本的媒体单元。
●Administered Objects --  由JMS Provider创建和定义,然后提供给JMS Clients使用。 JMS定义了两种 Administered Objects:
  1) ConnectionFactory:提供给Clients使用,用来建立和JMS Provider之间的连接。
  2) Destination:在Clients之间交互时,携载了消息对象的发送源与接收目标。
●JMS Clients是通过JNDI的方式来查找这些Administered Objects的。
●Non-JMS Clients -- 使用本地消息的API来实现的Clients。

此外,JMS可以在不同的域对象之间实现以下两种方式的消息传输机制:PTP(Point-to-Porint)和Pub/Sub(Publish-and-Subscribe),这两种方式 可 以并存于同一个应用之中。PTP是点对点传输消息,建立在消息队列的基础上,每个客户端对应一个消息队列,客户端发送消息到对方的消息队列中,从自己的消 息队列读取消息。 Pub/Sub是将消息定位到某个层次结构栏目的节点上,Pub/Sub通常是匿名的并能够动态发布消息,Pub/Sub必须保证某个节点的所有发布者 (Publisher)发布的信息准区无误地发送到这个节点的所有消息订阅者(Subscriber)。

我们不需要仔细去了解这两种方式的意义,JMS在此提供了一个更加统一的实现方式,该方式主要有以 下几个接口:ConnectionFactory、Connection、Destination、Session(消息交互线程的上下文环境)、MessageProducer(消息的发送者)、 MessageConsumer(消息的接收者)。

使用JMS API 不仅使通信变得松散耦合,而且它还使通信变得:
●异步: JMS 提供者将到来的消息发送给客户,客户不用发送请求接收消息。
●可靠: JMS API 确保消息传送一次而且只传送一次。可靠性差的应用程序可能会丢失消息或者重复接收消息

这里,我不想详细去写一个JMS应用的Demo。简单的就其API文档所提供的资料,来总结一下吧。

JMS应用中的消息发送

1、获得一个上下文环境:
Context ctx = new InitialContext();
2、通过JNDI查找来建立一个ConnectionFactory对象:
ConnectionFactory cf = (ConnectionFactory) ctx.lookup("java:JmsXA");
3、通过JNDI查找来建立一个或多个Destination对象:
Destination dest = (Queue) ctx.lookup("queue/A");  
4、通过ConnectionFactory创建一个JMS Connection连接:
Connection conn = cf.createConnection();
5、创建一个或多个JMS Session对象:
Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
6、使用一个Session对象和Destination对象,合作创建一个MessageProducer(消息发送端):
MessageProducer msgp = session.createProducer(dest);   //此处的dest已经被强制为P2P Queue对象
QueueSender sender = (QueueSender) msgp; 
//此处发送端指明采用的是 PTP的方式来实现JMS。当然你也可以用Pub/Sub的方式来实现
Destination dest = (Topic) ctx.lookup("queue/A");  
...
TopicPublisher sender = (TopicPublisher) msgp;
7、通过某个Session建立一个或多个JMS Message对象:
//此处仅以文字消息发送为例,您也可以建立和发送MapMessage, BytesMessage, ObjectMessage, StreamMessage
TextMessage msg = session.createTextMessage();
msg.setText("消息详细内容");
8、在已有的连接上,开始发布我们已经建立好的消息对象:
sender.send(msg);
9、关闭已经建立的连接:
conn.close();

JMS应用中的消息接收

1-5:同发送过程的初始化步骤1-5,因为是消息的接收方,JNDI的寻址方式应该同于发送方,这里的JNDI相当于是双方接头的暗号。
6、使用一个Session对象和Destination对象,合作创建一个MessageConsumer(消息接收端):
MessageConsumer msgconsumer = session.createConsumer(dest);
7、启动这个已经建立的连接,准备接收来自发送方的消息:
conn.start();
8、截获来自发送端的消息:
TextMessage msg = (TextMessage) msgconsumer.receive();
String message = msg.getText();
9、关闭已经建立的连接:
conn.close();

以上的消息接收端成功的接收了一条消息,如果我们要监控JMS消息的接收事件,需要在第7步之前,声明一个实现了MessageListener接口的对象:
MessageListener ml = new JmsListenner();  
msgConsumer.setMessageListener(ml); 
这里的JmsListenner是我们自定实现的一个MessageListener,其中关键的事件是:
public void onMessage(Message message);
一 个Session对象可以同时控制旗下的多个Consumer对象和MessageListener对象,但是这个Session是一个单线程模式的传递 机制,即:必须在当前Message对象被onMessage处理之后,才能继续接收下一条异步传送过来的Message对象。

总结

以上是我对JMS的一个初步的了解,也希望在以后的工作中对此有更进一步的认识,很乐意和大家探讨 :)

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics