訊息路由器

Spring Integration 原生提供專門的路由器類型,包括

  • HeaderValueRouter

  • PayloadTypeRouter

  • ExceptionTypeRouter

  • RecipientListRouter

  • XPathRouter

與許多其他 DSL IntegrationFlowBuilder EIP 方法一樣,route() 方法可以套用任何 AbstractMessageRouter 實作,或為了方便起見,使用 String 作為 SpEL 運算式或 ref-method 配對。此外,您可以設定帶有 lambda 的 route(),並將 lambda 用於 Consumer<RouterSpec<MethodInvokingRouter>>。Fluent API 也提供 AbstractMappingMessageRouter 選項,例如 channelMapping(String key, String channelName) 配對,如下列範例所示

@Bean
public IntegrationFlow routeFlowByLambda() {
    return IntegrationFlow.from("routerInput")
            .<Integer, Boolean>route(p -> p % 2 == 0,
                    m -> m.suffix("Channel")
                            .channelMapping(true, "even")
                            .channelMapping(false, "odd")
            )
            .get();
}

下列範例顯示一個簡單的基於運算式的路由器

@Bean
public IntegrationFlow routeFlowByExpression() {
    return IntegrationFlow.from("routerInput")
            .route("headers['destChannel']")
            .get();
}

routeToRecipients() 方法接受 Consumer<RecipientListRouterSpec>,如下列範例所示

@Bean
public IntegrationFlow recipientListFlow() {
    return IntegrationFlow.from("recipientListInput")
            .<String, String>transform(p -> p.replaceFirst("Payload", ""))
            .routeToRecipients(r -> r
                    .recipient("thing1-channel", "'thing1' == payload")
                    .recipientMessageSelector("thing2-channel", m ->
                            m.getHeaders().containsKey("recipient")
                                    && (boolean) m.getHeaders().get("recipient"))
                    .recipientFlow("'thing1' == payload or 'thing2' == payload or 'thing3' == payload",
                            f -> f.<String, String>transform(String::toUpperCase)
                                    .channel(c -> c.queue("recipientListSubFlow1Result")))
                    .recipientFlow((String p) -> p.startsWith("thing3"),
                            f -> f.transform("Hello "::concat)
                                    .channel(c -> c.queue("recipientListSubFlow2Result")))
                    .recipientFlow(new FunctionExpression<Message<?>>(m ->
                                    "thing3".equals(m.getPayload())),
                            f -> f.channel(c -> c.queue("recipientListSubFlow3Result")))
                    .defaultOutputToParentFlow())
            .get();
}

.routeToRecipients() 定義的 .defaultOutputToParentFlow() 可讓您將路由器的 defaultOutput 設定為閘道器,以便在主要流程中繼續處理不符的訊息。