JMS学习(四) Selector详解

本文介绍JMS中选择器的功能和使用方法,包括选择器的基本概念、实现方式、表达式定义等内容,帮助开发者理解如何利用选择器进行消息过滤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

     在掌握了消息的结构之后,我们接下来看一下JMS的一个重要功能:选择器。有些时候,作为消费者只希望处理自己感兴趣的消息。如果某个消息只有一个消费者,我们可以在让该客户端根据规则来处理自己感兴趣的消息,那些不满足某些规则的就直接替丢弃掉。

     但如果消息是广播的机制,那么让每个客户端都去做这样的处理,就加大了客户端的工作量,一种更好的方式,就是由消息提供者来完成消息的过滤和路由工作,这样就能大减轻客户端的工作量,消费者在真正处理的时候,完全不用关注对消息的过滤,可以只负责对消息的处理。也就是说,JMS的消息提供者可以保证其收到的消息都是其想要的消息。

     JMS中,这种机制是通过selector来实现的,本文则详细介绍一下selector.

二、实现方式

     在JMS里,selector并不是一个对象,而是一个字符串,更确切的说,是一个条件表达式,这个表达式并不仅限于处理逻辑表达式,而是一个跟SQL92语法类似的表达式。表达式中的变量必须为标准的消息头信息的key或者是某个属性的key,如果表达式计算结果为true,则表示该消息满足条件,接收端需要处理,如果为false,则表达接收端不需要处理。

  该表达式在创建一个消费者的时候进行指定,示例如下:

  MessageConsumer receiver = session.createConsumer(myDest, "articleType ='joke'");  

  则该receiver只会收到消息中有articleType属性,且其值为'joke'的消息。假设有两条消息,如下:

  message1.setStringProperty("articleType", "joke");  

  message2.setStringProperty("articleType", "pic");  

  很明显只有message1会被处理。

  

三、表达式定义

 

  可以看到其实设置一个selector还是比较简单的,如果对于SQL语法比较熟悉的话,那么对于表达式的理解和编写也会比较简单。一些重要的规则如下:

  1. 表达式的操作符不区分大小写,但通常约定为大写

  2. 表达式的变量名跟普通java变量名的命名规则一致,区分大小写,如articleType和articletype是两个不同的变量。

  3. 表达式的变量名必须是标准的头header名或者已存在的属性名,否则对应的值会为NULL

  4. 表达式的值不会进行类型转化,即假设有message2.setStringProperty("version", "1"); 那么表达式"version=1" 对于message2来说,结果是false.

  5. 支持基本的算术操作,逻辑操作,括号,取反等运算符

  6. 支持BETWEEN .. AND ... , IN (NOT IN)等操作

  7. 支持LIKE操作进行模糊匹配,%表示匹配多个任意字符,_表示匹配一个任意字符

  8. 支持IS NULL及IS NOT NULL

  9. 其它未提到的SQL 92 标准,可以认为能在WHERE语句后使用的表达式,在这儿都可以使用。

 

四、小结

  通过message的头信息和属性,结合selector,就能很方便的进行消息过滤。

 

  

 

转载于:https://www.cnblogs.com/macs524/p/5668778.html

### Java NIO 中的 Selector 详细介绍 #### 获取选择器实例 为了使用 `Selector`,首先需要创建一个 `Selector` 实例。这可以通过调用静态工厂方法 `open()` 来实现: ```java // 调用静态工厂方法 open()来获取 Selector 实例 Selector selector = Selector.open(); ``` 此过程初始化了一个新的 `Selector` 对象,该对象可用于注册通道并监控其就绪状态[^4]。 #### 注册通道到选择器 一旦有了 `Selector` 的实例,就可以将其与各种类型的 `SelectableChannel` 关联起来。关联的方式是通过向 `Selector` 注册这些通道,并指定要监听的操作类型(如读取、写入)。例如: ```java SelectionKey key = channel.register(selector, SelectionKey.OP_READ); ``` 这里,`channel` 是任何实现了 `SelectableChannel` 接口的对象之一,而 `OP_READ` 表明只关心这个特定通道上的可读事件[^3]。 #### 处理已选键集 当有至少一个通道准备好了所请求的操作时,可以选择一组已经准备好执行 I/O 操作的通道。这是通过调用 `select()` 方法完成的: ```java int readyChannels = selector.select(); if (readyChannels == 0) { continue; // 如果没有就绪的通道,则继续循环等待 } Set<SelectionKey> selectedKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectedKeys.iterator(); while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); if(selectionKey.isReadable()){ // 处理读操作... } if(selectionKey.isWritable()){ // 处理写操作... } iterator.remove(); // 移除当前处理过的key } ``` 这段代码展示了如何遍历由 `selector.select()` 返回的选择键集合,并针对每个键执行相应的逻辑。注意,在处理完某个键之后应该立即将其移出集合以防止重复处理同一项数据[^1]。 #### 取消注册或关闭资源 如果再需要监视某些通道的状态变化,可以从 `Selector` 上取消它们的注册;同样地,当整个程序结束运行前也应当记得释放掉所有占用着系统资源的对象: ```java selectionKey.cancel(); // 单独取消某条记录 selector.close(); // 完全终止选择器的工作 ``` 以上就是关于 Java NIO 下 `Selector` 组件较为完整的介绍以及基本的应用方式说明[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值