跳到主要内容

配置通用路由器

QWen Plus 中英对照 Configuring a Generic Router

Spring Integration 提供了一个通用路由器。您可以将其用于通用路由(与其他由 Spring Integration 提供的路由器不同,每个路由器都具有一些形式的 specialization)。

以下部分解释了一个带有 XML 组件的路由器配置。

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

<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"/>
xml

或者,ref 可以指向一个包含 @Router 注解的 POJO(稍后展示),或者你可以将 ref 与一个明确的方法名称结合使用。指定一个方法会应用与本文档后面 @Router 注解部分所描述的相同行为。以下示例定义了一个在其 ref 属性中指向 POJO 的路由器:

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

我们通常建议使用 ref 属性,如果自定义路由实现被引用在其他 <router> 定义中。但是,如果自定义路由实现应该仅限于单个 <router> 定义的作用域内,您可以提供一个内部 bean 定义,如下例所示:

<int:router method="someMethod" input-channel="input3"
default-output-channel="defaultOutput3">
<beans:bean class="org.foo.MyCustomRouter"/>
</int:router>
xml
备注

在同一 <router> 配置中使用 ref 属性和内部处理器定义是不允许的。这样做会创建一个模棱两可的条件并抛出异常。

important

如果 ref 属性引用了一个扩展自 AbstractMessageProducingHandler 的 bean(例如框架自身提供的路由器),配置会被优化为直接引用路由器。在这种情况下,每个 ref 属性必须引用一个独立的 bean 实例(或 prototype 作用域的 bean)或使用内嵌的 <bean/> 配置类型。然而,这种优化仅在你没有在路由器 XML 定义中提供任何路由器特定属性时适用。如果你无意中从多个 bean 引用了相同的消息处理器,你会得到一个配置异常。

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

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

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

};
}
java

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

@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
}

};
}
java

或者,你可以根据消息有效负载中的数据进行路由,如下例所示:

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