|
此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Integration 6.4.0! |
工艺路线单
从版本 4.1 开始, Spring 集成提供了路由单企业集成模式的实现。
它被实现为routingSlipmessage 标头,用于确定AbstractMessageProducingHandler实例,当outputChannel未为终端节点指定。
此模式在复杂的动态情况下非常有用,此时很难配置多个路由器来确定消息流。
当消息到达没有output-channel这routingSlip以确定将消息发送到的下一个通道。
当路由单用尽时,正常replyChannel处理简历。
路由单的配置显示为HeaderEnricheroption — 以分号分隔的路由单,其中包含path条目,如下例所示:
<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>
前面的示例具有:
-
一个
<context:property-placeholder>配置,以演示路由单中的条目path可以指定为可解析键。 -
这
<header-enricher><routing-slip>sub-元素用于填充RoutingSlipHeaderValueMessageProcessor到HeaderEnricher处理器。 -
这
RoutingSlipHeaderValueMessageProcessor接受String已解析的路由单数组path条目和返回值(来自processMessage()) 一个singletonMap使用path如key和0作为初始routingSlipIndex.
工艺路线单path条目可以包含MessageChannelbean 名称,RoutingSlipRouteStrategybean 名称和 Spring 表达式 (SpEL)。
这RoutingSlipHeaderValueMessageProcessor检查每个路由单path条目对BeanFactory在第一个processMessage调用。
它将条目(不是应用程序上下文中的 bean 名称)转换为ExpressionEvaluatingRoutingSlipRouteStrategy实例。RoutingSlipRouteStrategy条目被多次调用,直到它们返回 null 或空String.
由于路由单涉及getOutputChannelprocess 中,我们有一个 request-reply 上下文。
这RoutingSlipRouteStrategy已引入以确定下一个outputChannel,它使用requestMessage和reply对象。
此策略的实现应在应用程序上下文中注册为 Bean,并在路由单中使用其 Bean 名称path.
这ExpressionEvaluatingRoutingSlipRouteStrategyimplementation 的 implementation 的 S
它接受一个 SPEL 表达式和一个内部ExpressionEvaluatingRoutingSlipRouteStrategy.RequestAndReplyobject 用作 evaluation 上下文的根对象。
这是为了避免EvaluationContext为每个ExpressionEvaluatingRoutingSlipRouteStrategy.getNextPath()调用。
它是一个简单的 Java Bean,具有两个属性:Message<?> request和Object reply.
通过这个表达式实现,我们可以指定路由滑移path条目(例如,@routingSlipRoutingPojo.get(request, reply)和request.headers[myRoutingSlipChannel]),并避免为RoutingSlipRouteStrategy.
这requestMessageargument 始终为Message<?>.
根据上下文,回复对象可能是Message<?>一AbstractIntegrationMessageBuilder或任意应用程序域对象(例如,当它由服务激活器调用的 POJO 方法返回时)。
在前两种情况下,通常的Message属性 (payload和headers) 在使用 SPEL(或 Java 实现)时可用。
对于任意域对象,这些属性不可用。
因此,如果结果用于确定下一个路径,则在将路由单与 POJO 方法结合使用时要小心。 |
在分布式环境中涉及路由单时,建议不要对路由单使用内联表达式path.
此建议适用于分布式环境,例如跨 JVM 应用程序,使用request-reply通过消息代理(例如AMQP 支持或 JMS 支持),或使用持久性MessageStore (消息存储)在集成流中。
该框架使用RoutingSlipHeaderValueMessageProcessor以将它们转换为ExpressionEvaluatingRoutingSlipRouteStrategy对象,它们用于routingSlip消息标头。
由于这个类不是Serializable(它不能,因为它依赖于BeanFactory)、整个Message变得不可序列化,并且在任何分布式作中,我们最终都会得到一个NotSerializableException.
要克服此限制,请注册一个ExpressionEvaluatingRoutingSlipRouteStrategybean 替换为所需的 SPEL,并在路由单中使用其 bean 名称path配置。 |
对于 Java 配置,您可以添加RoutingSlipHeaderValueMessageProcessor实例添加到HeaderEnricherbean 定义,如下例所示:
@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已定义:
-
这
routingSlipIndex用于从工艺路线单中获取值path列表。 -
如果
routingSlipIndex是String,它用于从BeanFactory. -
如果返回的 Bean 是
MessageChannel,则它用作下一个outputChannel和routingSlipIndex在回复消息标头中递增(路由单path条目保持不变)。 -
如果返回的 Bean 是
RoutingSlipRouteStrategy及其getNextPath不会返回空的String,该结果将用作下一个outputChannel. 这routingSlipIndex保持不变。 -
如果
RoutingSlipRouteStrategy.getNextPath返回一个空的String或null这routingSlipIndex递增,并且getOutputChannelFromRoutingSlip为下一个 Routing Slip 递归调用path项目。 -
如果下一个工艺路线单
pathentry 不是String,它必须是RoutingSlipRouteStrategy. -
当
routingSlipIndex超过工艺路线单的大小pathlist 时,算法将移动到标准replyChannel页眉。