JMS API编程模型

3.JMS API编程模型

3.1.一个JMS应用由以下基本构件组成:
    受管对象:连接工厂和目的地
    连接
    会话(Session)
    消息生产者
    消息消费者
    消息

    3.2.受管对象:JMS应用的两个部分——目的地和连接工厂——最好的维护方式是让它们受管而不是编程解决。不同的JMS实现之间,这些对象底层的技术可能有非常大的不同。因此,管理这些对象术语其它的管理任务。
    JMS客户端可以轻便地通过接口访问这些对象,所以当系统有多个JMS实现时,客户端也只需很少甚至没有改动就可以运行。通常,管理员在JNDI名字空间配置了受管对象,JMS客户端使用JNDI API来找到这些对象。J2EE应用总是使用JNDI。
   
    3.2.1.连接工厂:连接工厂是一个客户端用来创建到JMS实现的连接的对象。连接工厂封装了一系列由管理员定义的连接参数。每个连接工厂都是 ConnctionFactory、QueueConnectionFactory或TopicConnectionFactory接口的实例。
    JMS客户端程序的开始,通常完成一个JNDI查找来获得连接工厂,强制转换为ConnectionFactory对象。比如:
    Context ctx = new InitialContext();
    ConnectionFactory connectionFactory = (ConnectionFactory)
    ctx.lookup("jms/ConnectionFactory");
    在J2EE应用里面,JMS受管对象自然是放在JNDI的‘jms’子上下文当中。

    3.2.2.目的地:目的地是一个(生产者)客户端用来指定产生的消息的目的地、(消费者)客户端指定消息源的对象。在P2P域,目的地叫做消息队列。在发布/订阅域,目的地叫做主题(topic)。
    用应用服务器创建目的地有两步。你创建一个指定了JNDI名字的JMS目的地资源,还需要创建一个该JNDI名字指向的物理目的地。
    一个JMS应用可以使用多个消息队列或主题(或两者都有)。
    另外,在一个客户端程序要查找一个连接工厂,你通常还要查找一个目的地。不像连接工厂,目的地是制定到一个域或其它。要创建一个用同一份代码使用主题或队 列的应用程序,你要将目的地强制转换和分配给Destination对象。要维护队列和主题的语义,无论如何,你要将目的地转换和赋值给相应的类型。下面 是示意代码:
    Destination myDest = (Destination) ctx.lookup("jms/MyTopic");
    Queue myQueue = (Queue) ctx.lookup("jms/MyQueue");
    有了通用接口,你可以混合或者匹配连接工厂和目的地。也就是说,使用ConnectionFactory接口,你可以查找一个 QueueConnectionFactory并将它用作Topic;你也可以查找一个TopicConnectionFactory并将它用作 Queue。程序的具体行为依赖于实际使用的目的地的类型而不是连接工厂的类型。

    3.3.连接:一个连接封装了道JMS实现的虚拟连接。一个连接可以表现为从客户端到JMS实现之间的一个打开的TCP/IP Socket。你使用连接来创建一个或多个会话(Session)。
    连接实现了Connection接口。当你拥有连接对象时,可以这样创建连接:
    Connection connection = connectionFactory.createConnection();
    //do something......
    connection.close();
    在应用程序退出前,你应该关闭任何创建的连接。关闭连接失败可能导致JMS实现无法释放资源。关闭一个连接也意味着关闭其会话、消息生产者和消费者。
    在你的应用程序可以消费消息之前,你应该调用连接的start方法;如果你想在不关闭连接的情况下暂时停止接收传递消息,可以调用连接的stop方法。

    3.4.会话:一个会话是单线程的生产/消费消息的上下文。你使用会话创建消息生产者、消费者和消息。会话序列化消息监听者的执行。
    会话通过将一组收/发的消息归为一个原子工作单元,来提供一个事务上下文。
    会话实现了Session接口,当你创建了连接对象后,可以用连接创建会话:
    Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
    第一个参数false表示该session不是事务性的;第二个表示当客户端正确接收消息后自动答谢
   
    3.5.消息生产者:消息生产者是由会话创建的用来发送消息到目的地的对象。它实现了MessageProducer接口。你可以使用Session为目的地创建一个MessageProducer,下面分别是queue和topic方式的代码:
    MessageProducer producer = session.createProducer(myQueue);
    MessageProducer producer = session.createProducer(myTopic);

消息消费者:
    消息消费者是一个由Session创建的用来接收发送打扫目的地的消息的对象。它实现了MessageConsumer接口。
    消息消费者允许JMS客户端向JMS实现注册感兴趣的目的地,JMS实现来管理从目的地到注册的消费者的消息传递。
    举个例子,你可以这样创建消费者:
        MessageConsumer consumer = session.createConsumer(myQueue);
        MessageConsumer consumer = session.createConsumer(myTopic);
    也可以使用Session.createDurableSubscriber创建发布/订阅域的持久化订阅者,这只在使用Topic时有效。
    创建了消费者之后,它就已经是激活的,就可以用来收消息了。调用其close方法切换到非激活状态。在连接没有调用start之前是无法接收消息的(始终要记住打开连接,忘记打开连接是JMS编程中最常见的错误)。要同步接收消息,代码可以这样:
        connection.start();
        Message m = consumer.receive();
        connection.start();
        Message m = consumer.receive(1000); // time out after a second
    而如果要使用异步方式接收消息,就应该使用监听器。
   
   
    消息监听器:
    消息监听器是一个完成消息异步事件处理的对象。它实现了MessageListener接口,该接口包含了一个onMessage方法。你应该在该方法内编写代码处理消息到达。
    你使用MessageConsumer的.setMessageListener方法注册消息监听器。比如:
        Listener myListener = new Listener();
        consumer.setMessageListener(myListener);
    当你为consumer注册了监听器之后,就可以connection.start()来接收消息传递了。(如果你在注册监听器之前调用连接的start方法,可鞥会丢失一些消息)
    监听器不指定具体的目的地类型。相同的监听器既可以从队列获取消息也可以从主题获取,具体依赖于消费者创建的是什么类型的目的地。然而,监听器一般都会预 期某一特定类型的消息类型和格式。此外,如果需要回复消息,监听器要么认定一个特定的目的地类型,要么从消息里得到目的地类型并创建响应的生产者。
    onMessage方法应该处理所有的异常。它不应该抛出检查异常,且抛出运行时异常会被认为是编程错误。
    会话用来创建消息消费者和序列化所有注册的监听器的执行。任意时间里,每个会话只有一个监听器运行。
    在J2EE平台中,消息驱动Bean是一种特殊类型的消息监听器。
   
    消息选择器:
    如果你的应用需要过滤收到的消息,可以使用JMS 消息选择器,它允许消费者指定感兴趣的消息。把消息过滤工作让消息选择器来做比自己用代码实现要好。消息选择器是一个包含了表达式的String。表达式基于SQL92条件表达式语法。详细略。。。。。。
   
    消息:
    JMS应用的终极目的就是构建一个能被其它应用消费用来生产和消费消息。JMS消息有基本的格式但具有很高的灵活性,允许你在异构平台的非JMS应用也能 创建相应的消息格式。一个JMS消息有3部分:header、属性、消息体。只有Header是必须有的,其它可以为空。
   
    消息Header:
        JMS消息header包含了一些有值的预定义字段,可以让客户端和JMS实现用来标识和路由消息。每一个消息都有一个唯一的id,在header中的 JMSMessageID字段中。另外一个JMSDestination字段,表示了消息要发送到哪个队列或者主题。其它的还有timestamp和优先 级等字段。
        每一个字段都有关联的getter和setter,这在Message接口中有文档注释。有的字段计划是由客户端来设置的,但喝多是由send/publish方法自动设置的,它将覆盖任何客户端设置的值。
   
    消息属性:
    如果你需要在消息内另外传值,可以创建或设置消息属性。这是一种和其它消息系统保持兼容的方式,或者你可以使用他们创建消息选择器。JMS API预定义了一些属性名,你要么使用预定义的,要么自己定义属性名。

 

 

转自:http://hi.baidu.com/franklee198/blog/item/7172a90f3846aae1aa6457c2.html

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值