如需使用最新稳定版本,请使用 Spring Integration 7.0.4spring-doc.cadn.net.cn

配置通用路由器

Spring Integration 提供了一个通用的路由器。 您可以使用它进行一般的路由(与 Spring Integration 提供的其他路由器不同,每个路由器都有某种形式的专业化)。spring-doc.cadn.net.cn

以下部分介绍使用 XML 组件的路由器配置。spring-doc.cadn.net.cn

router 元素提供了一种将路由器连接到输入通道的方式,并且可以接受可选的 default-output-channel 属性。
ref 属性引用了自定义路由器实现的 bean 名称(该实现必须扩展 AbstractMessageRouter)。
以下示例展示了三个通用路由器:spring-doc.cadn.net.cn

<int:router ref="payloadTypeRouter" input-channel="input1"
            default-output-channel="defaultOutput1"/>

<int:router ref="recipientListRouter" input-channel="input2"
            default-output-channel="defaultOutput2"/>

<int:router ref="customRouter" input-channel="input3"
            default-output-channel="defaultOutput3"/>

<beans:bean id="customRouterBean" class="org.foo.MyCustomRouter"/>

Alternatively, ref 可能指向包含 @Router 注解的一个POJO(稍后会展示),或者您可以将 ref 结合一个显式的函数名。 指定一个方法会使行为与文档中稍后的 @Router 注解部分描述的行为相同。 以下示例定义了一个路由器,其 ref 属性指向一个POJO:spring-doc.cadn.net.cn

<int:router input-channel="input" ref="somePojo" method="someMethod"/>

我们通常建议如果自定义路由器实现被其他<router>定义引用,则使用ref属性。 然而,如果自定义路由器实现应仅限于<router>的一个定义中,您可以提供一个内部bean定义,如下例所示:spring-doc.cadn.net.cn

<int:router method="someMethod" input-channel="input3"
            default-output-channel="defaultOutput3">
    <beans:bean class="org.foo.MyCustomRouter"/>
</int:router>
在同一<router>配置中同时使用ref属性和内部处理器定义是不允许的。 这样做会导致条件模糊,并抛出异常。
如果ref属性引用了一个扩展了AbstractMessageProducingHandler的bean(例如框架本身提供的路由器),则配置优化为直接引用该路由器。 在这种情况下,每个ref属性必须分别指向一个bean实例(或一个prototype-作用域的bean),或者使用内部<bean/>配置类型。 然而,此优化仅适用于在路由器XML定义中未提供任何路由器特定属性的情况。 如果您不小心从多个beans引用了同一个消息处理器,则会得到一个配置异常。

以下示例显示了等效的路由器配置在Java中:spring-doc.cadn.net.cn

@Bean
@Router(inputChannel = "routingChannel")
public AbstractMessageRouter myCustomRouter() {
    return new AbstractMessageRouter() {

        @Override
        protected Collection<MessageChannel> determineTargetChannels(Message<?> message) {
            return // determine channel(s) for message
        }

    };
}

以下示例展示了使用Java DSL配置的等效路由器:spring-doc.cadn.net.cn

@Bean
public IntegrationFlow routerFlow() {
    return IntegrationFlow.from("routingChannel")
            .route(myCustomRouter())
            .get();
}

public AbstractMessageRouter myCustomRouter() {
    return new AbstractMessageRouter() {

        @Override
        protected Collection<MessageChannel> determineTargetChannels(Message<?> message) {
            return // determine channel(s) for message
        }

    };
}

可以按消息负载中的数据进行路由,如下例所示:spring-doc.cadn.net.cn

@Bean
public IntegrationFlow routerFlow() {
    return IntegrationFlow.from("routingChannel")
            .route(String.class, p -> p.contains("foo") ? "fooChannel" : "barChannel")
            .get();
}