索赔检查
在前面的部分中,我们介绍了几个内容扩充器组件,这些组件可以帮助您处理消息缺少一条数据的情况。 我们还讨论了内容筛选,它允许您从消息中删除数据项。 但是,有时我们想暂时隐藏数据。 例如,在分布式系统中,我们可能会收到一条 payload 非常大的消息。 一些间歇性的消息处理步骤可能不需要访问这个 payload,有些可能只需要访问某些 header,因此在每个处理步骤中携带大消息 payload 可能会导致性能下降,可能会产生安全风险,并可能使调试更加困难。
存储在库中(或声明检查)模式描述了一种机制,该机制允许您将数据存储在众所周知的位置,同时仅维护指向该数据所在位置的指针(声明检查)。 您可以将该指针作为新消息的有效负载传递,从而让消息流中的任何组件在需要时立即获取实际数据。 这种方法与认证邮件流程非常相似,在认证邮件流程中,您会在邮箱中获得索赔支票,然后必须前往邮局领取您的实际包裹。 这与航班后或酒店领取行李的想法相同。
Spring 集成提供了两种类型的索赔检查转换器:
-
Incoming Claim Check Transformer
-
传出索赔检查转换器
可以使用方便的基于命名空间的机制来配置它们。
Incoming Claim Check Transformer
传入声明检查转换器通过将传入消息存储在由其属性标识的消息存储中来转换该消息。
以下示例定义了传入的索赔检查转换器:message-store
<int:claim-check-in id="checkin"
input-channel="checkinChannel"
message-store="testMessageStore"
output-channel="output"/>
在前面的配置中,在 上收到的消息将保存到使用属性标识的消息存储中,并使用生成的 ID 编制索引。
该 ID 是该邮件的声明检查。
声明检查还成为发送到 的新(转换的)消息的有效负载。input-channel
message-store
output-channel
现在,假设您在某个时候确实需要访问实际消息。 您可以手动访问邮件存储并获取邮件的内容,也可以使用相同的方法(创建转换器),只不过现在您使用传出索赔检查转换器将索赔检查转换为实际邮件。
以下清单概述了 incoming claim check transformer 的所有可用参数:
<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 定义的 ID ()。
此属性在元素中不可用。
自选。MessageTransformingHandler Chain |
3 | 此终端节点的接收消息通道。
此属性在元素中不可用。
自选。Chain |
4 | 对此索赔检查转换器要使用的 的引用。
如果未指定,则默认引用名为 .
自选。MessageStore messageStore |
5 | 指定此终端节点作为订阅者连接到通道时的调用顺序。
当该通道使用 dispatching 策略时,这一点尤其重要。
当此终端节点本身是具有队列的通道的轮询使用者时,它不起作用。
此属性在元素中不可用。
自选。failover Chain |
6 | 标识消息在此终端节点处理后发送到的消息通道。
此属性在元素中不可用。
自选。Chain |
7 | 指定向输出通道发送回复消息时要等待的最长时间(以毫秒为单位)。
默认为秒。
此属性在元素中不可用。
自选。30 Chain |
8 | 定义 poller。
此元素在元素中不可用。
自选。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 定义的 ID ()。
此属性在元素中不可用。
自选。MessageTransformingHandler Chain |
3 | 此终端节点的接收消息通道。
此属性在元素中不可用。
自选。Chain |
4 | 对此索赔检查转换器要使用的 的引用。
如果未指定,则默认引用名为 .
自选。MessageStore messageStore |
5 | 指定此终端节点作为订阅者连接到通道时的调用顺序。
当该通道使用 dispatching 策略时,这一点尤其重要。
当此终端节点本身是具有队列的通道的轮询使用者时,它不起作用。
此属性在元素中不可用。
自选。failover Chain |
6 | 标识消息在此终端节点处理后发送到的消息通道。
此属性在元素中不可用。
自选。Chain |
7 | 如果设置为 ,则此转换器将从 中删除该消息。
当 Message 只能被 “认领” 一次时,此设置非常有用。
它默认为 .
自选。true MessageStore false |
8 | 指定向输出通道发送回复消息时要等待的最长时间(以毫秒为单位)。
它默认为秒。
此属性在元素中不可用。
自选。30 Chain |
9 | 定义 poller。
此元素在元素中不可用。
自选。Chain |
领取一次
有时,特定消息只能声明一次。
打个比方,考虑处理飞机行李的过程。
您在出发时托运行李,并在抵达时领取行李。
行李一旦被认领,如果不先重新办理托运,就不能再次领取行李。
为了适应这种情况,我们在 transformer 上引入了一个 boolean 属性。
此属性默认设置为 。
但是,如果设置为 ,则会从 中删除已认领的消息,以便无法再次认领该消息。remove-message
claim-check-out
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"/>
关于 Message Store 的一句话
尽管我们很少关心声明检查的细节(只要它们有效),但您应该知道 Spring Integration 中实际声明检查(指针)的当前实现使用 UUID 来确保唯一性。
org.springframework.integration.store.MessageStore
是用于存储和检索消息的策略接口。
Spring 集成提供了两种方便的实现:
-
SimpleMessageStore
:基于内存的实现(默认,适合测试)Map
-
JdbcMessageStore
:通过 JDBC 使用关系数据库的实现