索赔检查
在前面的部分中,我们介绍了多个内容增强组件,可以帮助您处理消息缺少数据片段的情况。我们也讨论了内容过滤,它可以让您从消息中移除数据项。然而,有时我们希望暂时隐藏数据。例如,在分布式系统中,我们可能会收到带有非常大负载的消息。一些间歇性的消息处理步骤可能不需要访问此负载,而有些可能只需要访问某些头部信息,因此在每个处理步骤中携带大消息负载可能会导致性能下降、产生安全风险,并使调试变得更加困难。
库中的存储 (或称票据检查)模式描述了一种机制,它让你可以将数据存储在一个众所周知的地方,同时只维护指向该数据位置的指针(票据检查)。你可以将该指针作为新消息的有效载荷传递,从而使消息流中的任何组件在需要时都能获取实际数据。这种方法非常类似于认证邮件流程,在该流程中你会在邮箱中收到一个票据检查,然后必须去邮局领取实际的包裹。这也类似于航班后或在酒店的行李认领。
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元素内不可用。可选。
外发声明检查转换器
outgoing claim check 转换器允许您将带有声明检查有效负载的消息转换为以原始内容作为有效负载的消息。
<int:claim-check-out id="checkout"
        input-channel="checkoutChannel"
        message-store="testMessageStore"
        output-channel="output"/>
在上述配置中,input-channel 上接收到的消息应该具有一个声明检查作为其有效载荷。 outgoing claim check transformer 通过查询消息存储来查找由提供的声明检查标识的消息,将其转换为具有原始有效载荷的消息。然后,它将新检出的消息发送到 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 中移除,因此无法再次声明。
此功能对存储空间有影响,特别是在基于内存的 Map-based 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"/>
关于消息存储的一句话
虽然我们很少关心声明检查的细节(只要它们能正常工作),但你应该知道,Spring Integration 中实际声明检查(指针)的当前实现使用 UUID 来确保唯一性。
org.springframework.integration.store.MessageStore 是一个用于存储和检索消息的战略接口。Spring Integration 提供了两个便捷的实现:
- 
SimpleMessageStore:一个基于内存的、使用Map的实现(默认实现,适用于测试)
- 
JdbcMessageStore:一个通过 JDBC 使用关系数据库的实现