JMS消息选择器selector

业务场景:A系统通过一个队列(假定队列名是queueA)向B系统发送消息,后来业务调整,B系统拆分为两个系统B1,B2,分别处理不同的业务,并且分别都需要从queueA中获取不同的消息。为了不改变A系统的逻辑,即A系统还通过一个队列向B1,B2发不同的消息。B1,B2去自动选择得到属于自己的消息,可以使用消息过滤器。具体的做法是在创建消费者的时候指定选择器。

 

       /** Creates a <CODE>MessageConsumer</CODE> for the specified destination, 
      * using a message selector. 
      * Since <CODE>Queue</CODE> and <CODE>Topic</CODE> 
      * both inherit from <CODE>Destination</CODE>, they can be used in
      * the destination parameter to create a <CODE>MessageConsumer</CODE>.
      *
      * <P>A client uses a <CODE>MessageConsumer</CODE> object to receive 
      * messages that have been sent to a destination.
      *  
      *       
      * @param destination the <CODE>Destination</CODE> to access
      * @param messageSelector only messages with properties matching the
      * message selector expression are delivered. A value of null or
      * an empty string indicates that there is no message selector 
      * for the message consumer. 
      * 
      *  
      * @exception JMSException if the session fails to create a MessageConsumer
      *                         due to some internal error.
      * @exception InvalidDestinationException if an invalid destination
       * is specified.
     
      * @exception InvalidSelectorException if the message selector is invalid.
      *
      * @since 1.1 
      */
    MessageConsumer     
    createConsumer(Destination destination, java.lang.String messageSelector) 
    throws JMSException;

上面的方法中的第二个参数是选择器(也叫过滤器)的意思,选择器由三部分组成:标识符、常量、和比较运算符。其中标识符就是比较比较运算符中被比较的那一部分,标识符必须来自消息头或者是来自消息属性,它是区分大小写的,而且必须和属性或者是JMS消息头名称精确匹配。为了使用消息选择器,消息的生产者必须在发送消息之前指定属性或者是JMS消息头信息。下面的代码分别是生产者设置消息的自定义属性和消息头。eg..

            message.setJMSCorrelationID("123456789");
            message.setStringProperty("tianwang", "dihu");

可以用作标识符的消息头有这些:


上面的JMSCorrelationID用作标识符用得最多,并且经常用作JMS同步消息通信。关于JMS同步通信机制可以参考Spring的JmsTemplate的 源码。


针对上面生产者发送的带有标识符的消息,我们在session创建消费者的时候,代码可以如此写:

            MessageConsumer receiver = session.createConsumer(myDest, "tianwang1 ='dihu'");
            MessageConsumer receiver1 = session.createConsumer(myDest, "JMSMessageID ='123456789'");

关于选择器的格式:

消息选择器是基于SQL-92条件表达式语法的一部分。就是说上面代码第二个参数就是你平常写的sql语句的where后面的东东。。你肯定知道该怎么搞了。可以使用 =,like,not null等语句。

注意是SQL-92条件表达式语法的一部分。就是说有的语法不支持。我在测试的时候发现,如果想写不等于,必须使用“<>”这个符号,而“!=”就会报错“javax.jms.InvalidSelectorException:”。使用的时候肯定得自己测试一下OK不OK了。原因是"!="不是标准的SQL语句。因为只是 在某些版本的 SQL 中,操作符 <> 可以写为 !=。


写在最后:

  使用消息选择器,我们可以选择自己想要的有用信息,并且是在调用onMessage之前就进行选择,较少消费者的压力和处理逻辑。这个部分选择工作应该是交由JMS服务器做了。







评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值