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 中访问消息头的话。 |