跳到主要内容
版本:7.0.2

声明检查

DeepSeek V3 中英对照 Claim Check

在前面的章节中,我们介绍了几种内容增强器组件,它们可以帮助你处理消息缺少数据的情况。我们还讨论了内容过滤,它允许你从消息中移除数据项。然而,有时我们想要临时隐藏数据。例如,在分布式系统中,我们可能会收到一个包含非常大负载的消息。某些间歇性的消息处理步骤可能不需要访问这个负载,有些可能只需要访问特定的头部信息,因此让每个处理步骤都携带这个大负载的消息可能会导致性能下降,可能产生安全风险,并且可能使调试变得更加困难。

库存储模式(或称存根模式)描述了一种机制,允许您将数据存储在已知位置,同时仅保留指向该数据位置的指针(存根)。您可以将该指针作为新消息的有效载荷进行传递,从而使消息流中的任何组件在需要时都能立即获取实际数据。这种方法与挂号邮件流程非常相似:您在邮箱中收到一张取件单,然后必须前往邮局领取实际包裹。这与航班或酒店行李寄存的理念完全相同。

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>
  • 生命周期属性,指示该组件是否应在应用程序上下文启动期间启动。默认值为 true。此属性在 Chain 元素内部不可用。可选。

  • 标识底层 bean 定义 (MessageTransformingHandler) 的 ID。此属性在 Chain 元素内部不可用。可选。

  • 此端点的接收消息通道。此属性在 Chain 元素内部不可用。可选。

  • 引用此声明检查转换器要使用的 MessageStore。如果未指定,则默认引用名为 messageStore 的 bean。可选。

  • 指定当此端点作为订阅者连接到通道时的调用顺序。当通道使用 failover 调度策略时,这一点尤其重要。当此端点本身是带有队列的通道的轮询消费者时,此属性无效。此属性在 Chain 元素内部不可用。可选。

  • 标识消息经此端点处理后发送到的消息通道。此属性在 Chain 元素内部不可用。可选。

  • 指定向输出通道发送回复消息时的最大等待时间(以毫秒为单位)。默认值为 30 秒。此属性在 Chain 元素内部不可用。可选。

  • 定义一个轮询器。此元素在 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>
  • 生命周期属性,指示此组件是否应在应用程序上下文启动期间启动。默认值为 true。此属性在 Chain 元素内部不可用。可选。

  • 标识底层 bean 定义 (MessageTransformingHandler) 的 ID。此属性在 Chain 元素内部不可用。可选。

  • 此端点的接收消息通道。此属性在 Chain 元素内部不可用。可选。

  • 引用此声明检查转换器要使用的 MessageStore。如果未指定,默认引用名为 messageStore 的 bean。可选。

  • 指定当此端点作为订阅者连接到通道时的调用顺序。当该通道使用 failover 调度策略时,这一点尤其重要。当此端点本身是具有队列的通道的轮询消费者时,此属性无效。此属性在 Chain 元素内部不可用。可选。

  • 标识消息经此端点处理后发送到的消息通道。此属性在 Chain 元素内部不可用。可选。

  • 如果设置为 true,此转换器将从 MessageStore 中移除消息。当消息只能被“认领”一次时,此设置很有用。默认值为 false。可选。

  • 指定向输出通道发送回复消息时的最大等待时间(以毫秒为单位)。默认值为 30 秒。此属性在 Chain 元素内部不可用。可选。

  • 定义一个轮询器。此元素在 Chain 元素内部不可用。可选。

单次申领

有时,特定的消息必须仅被认领一次。类比来说,考虑处理飞机行李的过程。您在出发时托运行李,并在到达时认领。一旦行李被认领,除非重新托运,否则无法再次认领。为了适应这种情况,我们在 claim-check-out 转换器中引入了 remove-message 布尔属性。该属性默认设置为 false。然而,如果设置为 true,已认领的消息将从 MessageStore 中移除,从而无法再次被认领。

此功能在存储空间方面有一定影响,特别是对于基于内存 MapSimpleMessageStore,如果未能移除消息,最终可能导致 OutOfMemoryException。因此,如果您不希望出现多次声明,建议将 remove-message 属性的值设置为 true。以下示例展示了如何使用 remove-message 属性:

<int:claim-check-out id="checkout"
input-channel="checkoutChannel"
message-store="testMessageStore"
output-channel="output"
remove-message="true"/>

关于消息存储的说明

尽管我们很少关心认领单的细节(只要它们能正常工作),但你应该知道,Spring Integration 中当前实际认领单(指针)的实现使用了 UUID 来确保唯一性。

org.springframework.integration.store.MessageStore 是一个用于存储和检索消息的策略接口。Spring Integration 提供了两个便捷的实现:

  • SimpleMessageStore: 基于内存、Map 的实现(默认选项,适用于测试)

  • JdbcMessageStore: 使用 JDBC 连接关系型数据库的实现