Claim Check

在前面的部分中,我们介绍了几个内容扩充组件,它们可以帮助您处理消息缺少数据的情况。我们还讨论了内容筛选,这允许您从消息中删除数据项。但是,有时我们希望暂时隐藏数据。例如,在分布式系统中,我们可能会收到带有非常大的有效负载的消息。一些间歇性消息处理步骤可能不需要访问此有效负载,而另一些可能只需要访问某些头,因此在每个处理步骤中携带大的消息有效负载可能会导致性能下降、产生安全风险,并且可能使调试变得更加困难。 store in library(或索赔支票)模式描述了一种机制,它允许你在众所周知的位置存储数据,同时仅保留一个指针(索赔支票),指向数据的所在位置。你可以将该指针作为一条新消息的有效负载传递,从而让消息流中的任何组件在其需要时立即获取实际数据。此方法非常类似于认证邮件流程,你可以在信箱中收到索赔支票,然后必须去邮局索取实际包裹。它还与航班或酒店中的行李领取是一样的。 Spring Integration 提供两种声明检查转换器:

  • Incoming Claim Check Transformer

  • Outgoing Claim Check Transformer

有方便基于名称空间的机制可用于配置它们。

Incoming Claim Check Transformer

传入声明检查转换器通过将其存储在由其 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 元素内使用。可选。

Outgoing Claim Check Transformer

传出声明检查转换器允许您将带有声明检查有效负载的消息转换为具有原始内容作为其有效负载的消息。

<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 中删除消息。此设置在消息可以 “claimed” 一次时很有用。其默认为 false。可选。
8 指定向输出频道发送回复消息时等待的最长时间(以毫秒为单位)。其默认为 30 秒。此属性不可在 Chain 元素内使用。可选。
9 定义轮询器。此元素不可在 Chain 元素内使用。可选。

Claim Once

有时,特定消息只能声明一次。作为一个类比,考虑处理飞机行李的过程。您正在办理登机手续并领取行李。一旦行李被认领,如果没有先将行李重新托运,就不能再次认领。为了适应这种情况,我们在 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"/>

A Word on Message Store

尽管我们很少关心声明检查的详细信息(只要它们有效),您应该知道 Spring 集成中实际声明检查(指针)的当前实现使用 UUID 来确保唯一性。

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

  • SimpleMessageStore:基于内存的 Map 实现(默认值,适合测试)

  • JdbcMessageStore:使用基于 JDBC 的关系数据库实现