凭证检查
在前面的章节中,我们介绍了几个内容丰富器组件,它们可以帮助你处理消息中缺少数据的情况。我们还讨论了内容过滤,它允许你从消息中移除数据项。然而,有时我们希望暂时隐藏数据。例如,在分布式系统中,我们可能会收到一个带有非常大有效载荷的消息。一些中间的消息处理步骤可能不需要访问此有效载荷,有些可能只需要访问某些头部,因此将大型消息有效载荷通过每个处理步骤可能会导致性能下降,可能产生安全风险,并且可能使调试更加困难。
在库中存储(或认领凭证)模式描述了一种机制,它允许你将数据存储在一个众所周知的地方,同时只维护一个指向该数据位置的指针(一个认领凭证)。你可以将该指针作为新消息的有效载荷传递,从而让消息流中的任何组件在需要时立即获取实际数据。这种方法与挂号信流程非常相似,你会在邮箱中收到一张认领凭证,然后必须去邮局认领你的实际包裹。这与航班后或酒店中的行李认领也是相同的想法。
Spring Integration 提供了两种类型的认领凭证转换器
-
入站认领凭证转换器
-
出站认领凭证转换器
提供了方便的基于命名空间的机制来配置它们。
入站认领凭证转换器
入站认领凭证转换器通过将传入消息存储在其 message-store 属性标识的消息存储中来转换传入消息。以下示例定义了一个入站认领凭证转换器
<int:claim-check-in id="checkin"
input-channel="checkinChannel"
message-store="testMessageStore"
output-channel="output"/>
在前面的配置中,在 input-channel 上收到的消息被持久化到由 message-store 属性标识的消息存储中,并使用生成的 ID 进行索引。该 ID 是该消息的认领凭证。该认领凭证也成为发送到 output-channel 的新(转换后的)消息的有效载荷。
现在,假设在某个时候你需要访问实际消息。你可以手动访问消息存储并获取消息内容,或者你可以使用相同的方法(创建转换器),只是现在你通过使用出站认领凭证转换器将认领凭证转换为实际消息。
以下列表提供了入站认领凭证转换器所有可用参数的概述
<int:claim-check-in auto-startup="true" (1)
id="" (2)
input-channel="" (3)
message-store="messageStore" (4)
order="" (5)
output-channel="" (6)
send-timeout=""> (7)
<int:poller></int:poller> (8)
</int:claim-check-in>
| 1 | 生命周期属性,表示此组件是否应在应用程序上下文启动期间启动。它默认为 true。此属性在 Chain 元素内不可用。可选。 |
| 2 | 标识底层 bean 定义 (MessageTransformingHandler) 的 ID。此属性在 Chain 元素内不可用。可选。 |
| 3 | 此端点的接收消息通道。此属性在 Chain 元素内不可用。可选。 |
| 4 | 对要由该认领凭证转换器使用的 MessageStore 的引用。如果未指定,默认引用是名为 messageStore 的 bean。可选。 |
| 5 | 当此端点作为订阅者连接到通道时,指定调用的顺序。当该通道使用 failover 调度策略时,这尤其相关。当此端点本身是带有队列的通道的轮询消费者时,它没有效果。此属性在 Chain 元素内不可用。可选。 |
| 6 | 标识消息在被此端点处理后发送到的消息通道。此属性在 Chain 元素内不可用。可选。 |
| 7 | 指定发送回复消息到输出通道时等待的最大时间量(以毫秒为单位)。默认为 30 秒。此属性在 Chain 元素内不可用。可选。 |
| 8 | 定义一个轮询器。此元素在 Chain 元素内不可用。可选。 |
出站认领凭证转换器
出站认领凭证转换器允许你将带有认领凭证有效载荷的消息转换为带有原始内容作为其有效载荷的消息。
<int:claim-check-out id="checkout"
input-channel="checkoutChannel"
message-store="testMessageStore"
output-channel="output"/>
在前面的配置中,在 input-channel 上收到的消息的有效载荷应该是一个认领凭证。出站认领凭证转换器通过查询消息存储以获取由提供的认领凭证标识的消息,将其转换为带有原始有效载荷的消息。然后它将新取出的消息发送到 output-channel。
以下列表提供了出站认领凭证转换器所有可用参数的概述
<int:claim-check-out auto-startup="true" (1)
id="" (2)
input-channel="" (3)
message-store="messageStore" (4)
order="" (5)
output-channel="" (6)
remove-message="false" (7)
send-timeout=""> (8)
<int:poller></int:poller> (9)
</int:claim-check-out>
| 1 | 生命周期属性,表示此组件是否应在应用程序上下文启动期间启动。它默认为 true。此属性在 Chain 元素内不可用。可选。 |
| 2 | 标识底层 bean 定义 (MessageTransformingHandler) 的 ID。此属性在 Chain 元素内不可用。可选。 |
| 3 | 此端点的接收消息通道。此属性在 Chain 元素内不可用。可选。 |
| 4 | 对要由该认领凭证转换器使用的 MessageStore 的引用。如果未指定,默认引用是名为 messageStore 的 bean。可选。 |
| 5 | 当此端点作为订阅者连接到通道时,指定调用的顺序。当该通道使用 failover 调度策略时,这尤其相关。当此端点本身是带有队列的通道的轮询消费者时,它没有效果。此属性在 Chain 元素内不可用。可选。 |
| 6 | 标识消息在被此端点处理后发送到的消息通道。此属性在 Chain 元素内不可用。可选。 |
| 7 | 如果设置为 true,则此转换器会从 MessageStore 中移除消息。当消息只能被“认领”一次时,此设置很有用。它默认为 false。可选。 |
| 8 | 指定发送回复消息到输出通道时等待的最大时间量(以毫秒为单位)。它默认为 30 秒。此属性在 Chain 元素内不可用。可选。 |
| 9 | 定义一个轮询器。此元素在 Chain 元素内不可用。可选。 |
一次认领
有时,特定消息必须只能被认领一次。打个比方,考虑处理飞机行李的过程。你在出发时托运行李,在到达时认领行李。一旦行李被认领,除非再次托运,否则不能再次认领。为了适应这种情况,我们在 claim-check-out 转换器上引入了一个 remove-message 布尔属性。此属性默认设置为 false。但是,如果设置为 true,则认领的消息会从 MessageStore 中移除,使其不能再次被认领。
此功能对存储空间有影响,尤其是在基于内存 Map 的 SimpleMessageStore 的情况下,如果未能移除消息,最终可能导致 OutOfMemoryException。因此,如果您不期望多次认领,我们建议您将 remove-message 属性的值设置为 true。以下示例展示了如何使用 remove-message 属性
<int:claim-check-out id="checkout"
input-channel="checkoutChannel"
message-store="testMessageStore"
output-channel="output"
remove-message="true"/>