Routers and the Spring Expression Language (SpEL)

有时,路由逻辑可能会比较简单,而且为它编写一个单独的类并将其配置为 bean 可能会感觉有点过分。自 Spring Integration 2.0 起,我们提供了一种替代方案,它允许你使用 SpEL 来实现先前需要自定义 POJO 路由器的简单计算。

Sometimes, the routing logic may be simple, and writing a separate class for it and configuring it as a bean may seem like overkill. As of Spring Integration 2.0, we offer an alternative that lets you use SpEL to implement simple computations that previously required a custom POJO router.

关于 Spring 表达式语言的更多信息,请参阅 relevant chapter in the Spring Framework Reference Guide

For more information about the Spring Expression Language, see the relevant chapter in the Spring Framework Reference Guide.

通常,SpEL 表达式会被计算,并且它的结果会被映射到一个信道,如下例所示:

Generally, a SpEL expression is evaluated and its result is mapped to a channel, as the following example shows:

<int:router input-channel="inChannel" expression="payload.paymentType">
    <int:mapping value="CASH" channel="cashPaymentChannel"/>
    <int:mapping value="CREDIT" channel="authorizePaymentChannel"/>
    <int:mapping value="DEBIT" channel="authorizePaymentChannel"/>
</int:router>

以下示例展示了在 Java 中配置的等效路由器:

The following example shows the equivalent router configured in Java:

@Router(inputChannel = "routingChannel")
@Bean
public ExpressionEvaluatingRouter router() {
    ExpressionEvaluatingRouter router = new ExpressionEvaluatingRouter("payload.paymentType");
    router.setChannelMapping("CASH", "cashPaymentChannel");
    router.setChannelMapping("CREDIT", "authorizePaymentChannel");
    router.setChannelMapping("DEBIT", "authorizePaymentChannel");
    return router;
}

以下示例展示了使用 Java DSL 配置的等效路由器:

The following example shows the equivalent router configured in the Java DSL:

@Bean
public IntegrationFlow routerFlow() {
    return IntegrationFlow.from("routingChannel")
        .route("payload.paymentType", r -> r
            .channelMapping("CASH", "cashPaymentChannel")
            .channelMapping("CREDIT", "authorizePaymentChannel")
            .channelMapping("DEBIT", "authorizePaymentChannel"))
        .get();
}

为了让事情变得更简单,SpEL 表达式可以计算为一个信道名称,如下面的表达式所示:

To simplify things even more, the SpEL expression may evaluate to a channel name, as the following expression shows:

<int:router input-channel="inChannel" expression="payload + 'Channel'"/>

在之前的配置中,结果信道是由 SpEL 表达式计算的,该表达式连接 payload 的值与字面量 String“Channel”。

In the preceding configuration, the result channel is computed by the SpEL expression, which concatenates the value of the payload with the literal String, 'Channel'.

SpEL 用于配置路由器的另一个优点是,一个表达式可以返回一个 Collection,从而有效地使每个 <router> 成为一个接受者列表路由器。只要表达式返回多个信道值,消息就会被转发到每个信道。以下示例展示了此类表达式:

Another virtue of SpEL for configuring routers is that an expression can return a Collection, effectively making every <router> a recipient list router. Whenever the expression returns multiple channel values, the message is forwarded to each channel. The following example shows such an expression:

<int:router input-channel="inChannel" expression="headers.channels"/>

在上面的配置中,如果消息包含一个名为“channels”且该标头的值是信道名称 List 的标头,消息就会被发送到列表中的每个信道。当你需要选择多个信道时,你可能会发现集合投影和集合选择表达式也很有用。更多信息,请参见:

In the above configuration, if the message includes a header with a name of 'channels' and the value of that header is a List of channel names, the message is sent to each channel in the list. You may also find collection projection and collection selection expressions useful when you need to select multiple channels. For further information, see: