設定通用路由器
Spring Integration 提供通用路由器。您可以將其用於通用路由(與 Spring Integration 提供的其他路由器相反,後者各有某種形式的專業化)。
以下章節說明使用 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"/>
或者,ref
可以指向包含 @Router
註解(稍後顯示)的 POJO,或者您可以將 ref
與明確的方法名稱結合使用。指定方法會套用本文稍後 @Router
註解章節中描述的相同行為。以下範例定義了一個路由器,該路由器在其 ref
屬性中指向 POJO
<int:router input-channel="input" ref="somePojo" method="someMethod"/>
如果自訂路由器實作在其他 <router>
定義中被參考,我們通常建議使用 ref
屬性。但是,如果自訂路由器實作應限定於單個 <router>
定義,您可以提供內部 Bean 定義,如下列範例所示
<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 定義中提供任何路由器特定的屬性時,此最佳化才適用。如果您不小心從多個 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 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
}
};
}
或者,您可以根據訊息酬載中的資料進行路由,如下列範例所示
@Bean
public IntegrationFlow routerFlow() {
return IntegrationFlow.from("routingChannel")
.route(String.class, p -> p.contains("foo") ? "fooChannel" : "barChannel")
.get();
}