跳到主要内容
版本:7.0.2

Kotlin DSL

DeepSeek V3 中英对照 Kotlin DSL

Kotlin DSL 是 Java DSL 的包装器和扩展,旨在通过 Kotlin 语言特有的结构以及与现有 Java API 的互操作性,使 Spring Integration 在 Kotlin 上的开发尽可能流畅和直观。

开始使用所需的一切,仅仅是一个对 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,作用于 KotlinIntegrationFlowDefinitionIntegrationFlowDefinition 的 Kotlin 包装器),并生成一个常规的 IntegrationFlow lambda 实现。更多重载的 integrationFlow() 变体请参见下文。

许多其他场景需要 IntegrationFlow 从数据源启动(例如 JdbcPollingChannelAdapterJmsInboundGateway 或仅是一个现有的 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 的消费者,可以将流程的其余部分声明为 IntegrationFlow lambda,从而复用上述经验,同时避免在最后调用 get()。例如:

@Bean
fun functionFlow() =
integrationFlow<Function<String, String>>({ beanName("functionGateway") }) {
transform<String> { it.toUpperCase() }
}

@Bean
fun messageSourceFlow() =
integrationFlow({ "testSource" },
{ poller { it.fixedDelay(10).maxMessagesPerPoll(1) } }) {
channel { queue("fromSupplierQueue") }
}

此外,Kotlin还为Java DSL API提供了扩展,这些扩展需要针对Kotlin结构进行一些优化。例如,IntegrationFlowDefinition<*> 需要为许多带有 Class<P> 参数的方法进行具体化处理:

@Bean
fun convertFlow() =
integrationFlow("convertFlowInput") {
convert<TestPojo>()
}
备注

如果需要在操作符的 lambda 表达式中访问消息头,具体化的类型可以是完整的 Message<*>