Kotlin DSL

Kotlin DSL 是 Java DSL 的包装器和扩展,旨在使 Kotlin 上的 Spring Integration 开发尽可能平滑和直接,并且可以与现有的 Java API 和特定于 Kotlin 语言的结构互操作。

The Kotlin DSL is a wrapper and extension to Java DSL and aimed to make Spring Integration development on Kotlin as smooth and straightforward as possible with interoperability with the existing Java API and Kotlin language-specific structures.

你入门所需的一切只是一个 org.springframework.integration.dsl.integrationFlow 导入——Kotlin DSL 的重载全局函数。

All you need to get started is just an import for org.springframework.integration.dsl.integrationFlow - an overloaded global function for Kotlin DSL.

对于作为 lambda 表达式的 IntegrationFlow 定义,我们通常不需要 Kotlin 的其他任何内容,只需像这样声明一个 bean:

For IntegrationFlow definitions as lambdas we typically don’t need anything else from Kotlin and just declare a bean like this:

@Bean
fun oddFlow() =
IntegrationFlow { flow ->
    flow.handle<Any> { _, _ -> "odd" }
}

在这种情况下,Kotlin 会理解应该将 lambda 表达式转换为 IntegrationFlow 匿名实例,并且目标 Java DSL 处理器会正确地将此构造解析为 Java 对象。

In this case Kotlin understands that the lambda should be translated into IntegrationFlow anonymous instance and target Java DSL processor parses this construction properly into Java objects.

作为上述构造的替代方法,并且为了与下面解释的用例保持一致,应为以*构建*模式样式声明集成流使用特定于 Kotlin 的 DSL:

As an alternative to the construction above and for consistency with use-cases explained below, a Kotlin-specific DSL should be used for declaring integration flows in the builder pattern style:

@Bean
fun flowLambda() =
    integrationFlow {
        filter<String> { it === "test" }
        wireTap {
                    handle { println(it.payload) }
                }
        transform<String> { it.toUpperCase() }
    }

这种全局 integrationFlow() 函数需要在构建器样式中为 KotlinIntegrationFlowDefinitionIntegrationFlowDefinition 的 Kotlin 封装)提供一个 lambda,并生成常规 IntegrationFlow lambda 实现。在下面查看更多重载的 integrationFlow() 变体。

Such a global integrationFlow() function expects a lambda in builder style for a KotlinIntegrationFlowDefinition (a Kotlin wrapper for the IntegrationFlowDefinition) and produces a regular IntegrationFlow lambda implementation. See more overloaded integrationFlow() variants below.

许多其他场景需要从数据源(例如 JdbcPollingChannelAdapterJmsInboundGateway 或仅仅一个现有的 MessageChannel)启动 IntegrationFlow。为此,Spring Integration Java DSL 提供了 IntegrationFlow fluent API 及其大量重载的 from() 方法。此 API 也可用于 Kotlin:

Many other scenarios require an IntegrationFlow to be started from source of data (e.g. JdbcPollingChannelAdapter, JmsInboundGateway or just an existing MessageChannel). For this purpose, the Spring Integration Java DSL provides an IntegrationFlow fluent API with its large number of overloaded from() methods. This API can be used in Kotlin as well:

@Bean
fun flowFromSupplier() =
         IntegrationFlow.fromSupplier({ "bar" }) { e -> e.poller { p -> p.fixedDelay(10).maxMessagesPerPoll(1) } }
                 .channel { c -> c.queue("fromSupplierQueue") }
                 .get()

但不幸的是,并不是所有 from() 方法都与 Kotlin 结构兼容。为了弥补这一差距,本项目围绕 IntegrationFlow fluent API 提供了一个 Kotlin DSL。它被实现为一组重载的 integrationFlow() 函数。利用 KotlinIntegrationFlowDefinition 的使用者来声明流程的其余部分,作为 IntegrationFlow lambda 来重用上述体验,并且还可以避免在最后调用 get()。例如:

But unfortunately not all from() methods are compatible with Kotlin structures. To fix the gap, this project provides a Kotlin DSL around an IntegrationFlow fluent API. It is implemented as a set of overloaded integrationFlow() functions. With a consumer for a KotlinIntegrationFlowDefinition to declare the rest of the flow as an IntegrationFlow lambda to reuse the mentioned above experience and also avoid get() call in the end. For example:

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

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

In addition, Kotlin extensions are provided for the Java DSL API which needs some refinement for Kotlin structures. For example IntegrationFlowDefinition<*> requires a reifying for many methods with Class<P> argument:

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

如果需要在运算符的 lambda 中访问头信息,则实体化类型可以是一个完整的 Message<*>

The reified type can be a whole Message<*> if there need access to headers as well in the lambda of the operator.