Kotlin DSL
Kotlin DSL 是 Java DSL 的封裝和擴充套件,旨在透過與現有 Java API 和 Kotlin 語言特定結構的互操作性,使 Spring Integration 在 Kotlin 上的開發儘可能順暢和直接。
開始使用 Kotlin DSL,你只需要匯入 org.springframework.integration.dsl.integrationFlow
—— 一個為 Kotlin DSL 過載的全域性函式。
對於定義為 lambda 表示式的 IntegrationFlow
,我們通常不需要 Kotlin 的其他功能,只需像這樣宣告一個 Bean 即可
@Bean
fun oddFlow() =
IntegrationFlow { flow ->
flow.handle<Any> { _, _ -> "odd" }
}
在這種情況下,Kotlin 會將該 lambda 表示式翻譯成 IntegrationFlow
的匿名例項,而目標 Java DSL 處理器能夠正確地將這種構造解析成 Java 物件。
作為上述構造的替代方案,併為了與下面解釋的使用場景保持一致,應使用特定於 Kotlin 的 DSL 以構建器模式風格宣告整合流
@Bean
fun flowLambda() =
integrationFlow {
filter<String> { it === "test" }
wireTap {
handle { println(it.payload) }
}
transform<String> { it.toUpperCase() }
}
這樣一個全域性 integrationFlow()
函式期望一個構建器風格的 lambda 表示式用於 KotlinIntegrationFlowDefinition
(一個 IntegrationFlowDefinition
的 Kotlin 封裝器),並生成一個常規的 IntegrationFlow
lambda 實現。更多過載的 integrationFlow()
變體請參見下文。
許多其他場景需要 IntegrationFlow
從資料來源(例如 JdbcPollingChannelAdapter
、JmsInboundGateway
或只是一個現有的 MessageChannel
)開始。為此,Spring Integration Java DSL 提供了 IntegrationFlow
的流暢 API 及其大量過載的 from()
方法。此 API 也可以在 Kotlin 中使用
@Bean
fun flowFromSupplier() =
IntegrationFlow.fromSupplier({ "bar" }) { e -> e.poller { p -> p.fixedDelay(10).maxMessagesPerPoll(1) } }
.channel { c -> c.queue("fromSupplierQueue") }
.get()
但不幸的是,並非所有 from()
方法都與 Kotlin 結構相容。為了彌補這一差距,本專案提供了圍繞 IntegrationFlow
流暢 API 的 Kotlin DSL。它實現為一組過載的 integrationFlow()
函式。透過一個 KotlinIntegrationFlowDefinition
的 consumer 來宣告流的其餘部分作為一個 IntegrationFlow
lambda,以重用上述經驗,並避免在最後呼叫 get()
。例如
@Bean
fun functionFlow() =
integrationFlow<Function<String, String>>({ beanName("functionGateway") }) {
transform<String> { it.toUpperCase() }
}
@Bean
fun messageSourceFlow() =
integrationFlow(MessageProcessorMessageSource { "testSource" },
{ poller { it.fixedDelay(10).maxMessagesPerPoll(1) } }) {
channel { queue("fromSupplierQueue") }
}
此外,還為需要針對 Kotlin 結構進行一些改進的 Java DSL API 提供了 Kotlin 擴充套件。例如,IntegrationFlowDefinition<*>
對於許多帶有 Class<P>
引數的方法需要進行具體化(reifying)
@Bean
fun convertFlow() =
integrationFlow("convertFlowInput") {
convert<TestPojo>()
}
具體化型別可以是整個 Message<*> ,如果需要在運算子的 lambda 中訪問訊息頭的話。 |