Groovy DSL
开始使用所需的一切仅仅是一个导入: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 提供了一个 IntegrationFlow 工厂,其中包含一系列重载的 from() 方法。该工厂同样可在 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' }
}
}