Groovy DSL

Groovy DSL 是 Java DSL 的包装器和扩展。我们的主要目标是使 Spring Integration 在 Groovy 上的开发尽可能流畅和直接,并与现有的 Java DSL 以及一些 Groovy 扩展或特定于语言的结构实现互操作性。该实现是 Groovy 支持 模块的一部分。

你只需要导入 `import static org.springframework.integration.groovy.dsl.IntegrationGroovyDsl.integrationFlow` — 一个包含 Groovy DSL 重载工厂方法的类即可开始。

对于作为 lambda 的 `IntegrationFlow` 定义,我们通常不需要 Groovy 的其他任何东西,只需像这样声明一个 bean:

@Bean
IntegrationFlow oddFlow() {
    { IntegrationFlowDefinition flow ->
	    flow.handle(Object, { p, h -> 'odd' })
    }
}

在这种情况下,Groovy 理解闭包应该转换为 `IntegrationFlow` 匿名实例,目标 Java DSL 处理器会将此结构正确解析为 Java 对象。

作为上述结构的替代方案,并且为了与下面解释的用例保持一致,`spring-integration-groovy` 模块提供了一个特定于 Groovy 的 DSL,用于以**构建器**模式样式声明集成流。

@Bean
flowLambda() {
    integrationFlow {
        filter String, { it == 'test' }, { id 'filterEndpoint' }
        wireTap integrationFlow {
            channel { queue 'wireTapChannel' }
        }
        delay {
		    messageGroupId 'delayGroup'
		    defaultDelay 100
        }
        transform {
		    transformer { it.toUpperCase() }
            expectedType String
        }
    }
}

这样的全局 `integrationFlow()` 函数期望一个构建器样式的闭包,用于 `GroovyIntegrationFlowDefinition`(`IntegrationFlowDefinition` 的 Groovy 包装器),并生成一个常规的 `IntegrationFlow` lambda 实现。请参见下面更多重载的 `integrationFlow()` 变体。

许多其他场景需要从数据源启动 `IntegrationFlow`(例如 `JdbcPollingChannelAdapter`、`JmsInboundGateway` 或只是一个现有的 `MessageChannel`)。为此,Spring Integration Java DSL 提供了一个具有多个重载 `from()` 方法的 `IntegrationFlow` 工厂。此工厂也可以在 Groovy 中使用。

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

但不幸的是,并非所有 `from()` 方法都与 Groovy 结构兼容。为了解决这个问题,Spring Integration 提供了一个围绕 `IntegrationFlow` 工厂的 Groovy DSL 工厂。它实现为一组重载的 `integrationFlow()` 函数。它使用 `GroovyIntegrationFlowDefinition` 的使用者来声明流的其余部分,作为一个 `IntegrationFlow` 闭包,以重用上述经验,并避免最终需要 `get()` 调用。例如:

@Bean
functionFlow() {
    integrationFlow Function<byte[], String>,
            { beanName 'functionGateway' },
            {
                transform {
		            transformer Transformers.objectToString()
                    id 'objectToStringTransformer'
                }
                transform {
		            transformer { it.toUpperCase() }
                    expectedType String
                }
                splitWith {
                    expectedType Message<?>
                    function { it.payload }
                }
                splitWith {
                    expectedType Object
                    id 'splitterEndpoint'
                    function { it }
                }
                resequence()
                aggregate {
                    id 'aggregator'
                    outputProcessor { it.one }
                }
            }
}

@Bean
someFlow() {
    integrationFlow ({ 'test' },
            {
                poller { it.trigger new OnlyOnceTrigger() }
                id 'pollingSource'
            })
            {
                log LoggingHandler.Level.WARN, 'test.category'
                channel { queue 'pollerResultChannel' }
            }
}