此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Integration 6.5.1spring-doc.cadn.net.cn

路由单

从版本 4.1 开始,Spring Integration 提供了路由单企业集成模式的实现。 它被实现为routingSlip消息头,用于确定AbstractMessageProducingHandler实例,当outputChannel未为终结点指定。 此模式在复杂的动态情况下非常有用,因为配置多个路由器来确定消息流可能会变得困难。 当消息到达没有output-channelroutingSlip以确定将消息发送到的下一个通道。 当路由滑移耗尽时,正常replyChannel处理简历。spring-doc.cadn.net.cn

路由单的配置显示为HeaderEnricheroption — 一个以分号分隔的路由单,其中包含path条目,如以下示例所示:spring-doc.cadn.net.cn

<util:properties id="properties">
    <beans:prop key="myRoutePath1">channel1</beans:prop>
    <beans:prop key="myRoutePath2">request.headers[myRoutingSlipChannel]</beans:prop>
</util:properties>

<context:property-placeholder properties-ref="properties"/>

<header-enricher input-channel="input" output-channel="process">
    <routing-slip
        value="${myRoutePath1}; @routingSlipRoutingPojo.get(request, reply);
               routingSlipRoutingStrategy; ${myRoutePath2}; finishChannel"/>
</header-enricher>

前面的示例具有:spring-doc.cadn.net.cn

  • 一个<context:property-placeholder>配置,以证明路由单中的条目path可以指定为可解析的键。spring-doc.cadn.net.cn

  • <header-enricher> <routing-slip>子元素用于填充RoutingSlipHeaderValueMessageProcessorHeaderEnricher处理器。spring-doc.cadn.net.cn

  • RoutingSlipHeaderValueMessageProcessor接受String已解析的路由滑移数组path条目和返回(从processMessage()) 一个singletonMap使用pathkey0作为初始routingSlipIndex.spring-doc.cadn.net.cn

路由单path条目可以包含MessageChannel豆名,RoutingSlipRouteStrategybean 名称和 Spring 表达式 (SpEL)。 这RoutingSlipHeaderValueMessageProcessor检查每个路由单path条目对BeanFactory在第一个processMessage调用。 它将条目(在应用程序上下文中不是 bean 名称)转换为ExpressionEvaluatingRoutingSlipRouteStrategy实例。RoutingSlipRouteStrategy条目被多次调用,直到它们返回 null 或空String.spring-doc.cadn.net.cn

由于路由单涉及getOutputChannelprocess,我们有一个请求-回复上下文。 这RoutingSlipRouteStrategy已引入以确定下一个outputChannel使用requestMessagereply对象。 此策略的实现应在应用程序上下文中注册为 bean,并在路由单中使用其 bean 名称path. 这ExpressionEvaluatingRoutingSlipRouteStrategy提供了实现。 它接受 SpEL 表达式和内部ExpressionEvaluatingRoutingSlipRouteStrategy.RequestAndReply对象用作评估上下文的根对象。 这是为了避免EvaluationContext为每个人创建ExpressionEvaluatingRoutingSlipRouteStrategy.getNextPath()调用。 它是一个简单的 Java bean,具有两个属性:Message<?> requestObject reply. 通过这个表达式实现,我们可以指定路由单path条目(例如,@routingSlipRoutingPojo.get(request, reply)request.headers[myRoutingSlipChannel])并避免为RoutingSlipRouteStrategy.spring-doc.cadn.net.cn

requestMessage参数始终是一个Message<?>. 根据上下文,回复对象可能是Message<?>AbstractIntegrationMessageBuilder,或任意应用程序域对象(例如,当它由服务激活器调用的 POJO 方法返回时)。 在前两种情况下,通常的Message属性 (payloadheaders) 在使用 SpEL(或 Java 实现)时可用。 对于任意域对象,这些属性不可用。 因此,如果将结果用于确定下一条路径,则在将路由单与 POJO 方法结合使用时要小心。
如果分布式环境中涉及布线单,我们建议不要对布线单使用内联表达式path. 此建议适用于分布式环境,例如跨 JVM 应用程序,使用request-reply通过消息代理(例如AMQP 支持JMS 支持),或使用MessageStore (消息存储)在集成流程中。 该框架使用RoutingSlipHeaderValueMessageProcessor将它们转换为ExpressionEvaluatingRoutingSlipRouteStrategy对象,它们用于routingSlip消息头。 由于这个类不是Serializable(不可能,因为它取决于BeanFactory),整个Message变得不可序列化,并且在任何分布式作中,我们最终都会得到一个NotSerializableException. 要克服此限制,请注册一个ExpressionEvaluatingRoutingSlipRouteStrategybean 具有所需的 SpEL,并在路由单中使用其 bean 名称path配置。

对于 Java 配置,您可以添加一个RoutingSlipHeaderValueMessageProcessorinstance 添加到HeaderEnricherbean 定义,如以下示例所示:spring-doc.cadn.net.cn

@Bean
@Transformer(inputChannel = "routingSlipHeaderChannel")
public HeaderEnricher headerEnricher() {
    return new HeaderEnricher(Collections.singletonMap(IntegrationMessageHeaderAccessor.ROUTING_SLIP,
            new RoutingSlipHeaderValueMessageProcessor("myRoutePath1",
                                                       "@routingSlipRoutingPojo.get(request, reply)",
                                                       "routingSlipRoutingStrategy",
                                                       "request.headers[myRoutingSlipChannel]",
                                                       "finishChannel")));
}

当端点生成回复并且没有outputChannel已定义:spring-doc.cadn.net.cn

  • routingSlipIndex用于从路由单获取值path列表。spring-doc.cadn.net.cn

  • 如果routingSlipIndexString,用于从BeanFactory.spring-doc.cadn.net.cn

  • 如果返回的 bean 是MessageChannel,它用作下一个outputChannelroutingSlipIndex在回复邮件头中递增(路由单path条目保持不变)。spring-doc.cadn.net.cn

  • 如果返回的 bean 是RoutingSlipRouteStrategy及其getNextPath不返回空的String,则该结果将用作下一个 Bean 名称outputChannel. 这routingSlipIndex保持不变。spring-doc.cadn.net.cn

  • 如果RoutingSlipRouteStrategy.getNextPath返回一个空的StringnullroutingSlipIndex递增,并且getOutputChannelFromRoutingSlip为下一个布线单递归调用path项目。spring-doc.cadn.net.cn

  • 如果下一个路由单path条目不是String,它必须是RoutingSlipRouteStrategy.spring-doc.cadn.net.cn

  • routingSlipIndex超过布线单的大小pathlist,则算法将移至标准的默认行为replyChannel页眉。spring-doc.cadn.net.cn