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