Groovy DSL

Groovy DSL 是對 Java DSL 的封裝和擴充套件。我們的主要目標是使 Groovy 上的 Spring Integration 開發儘可能平滑和直接,並能與現有 Java DSL 以及一些 Groovy 擴充套件或語言特定結構進行互操作。此實現是 Groovy 支援 模組的一部分。

要開始使用,您只需要匯入 import static org.springframework.integration.groovy.dsl.IntegrationGroovyDsl.integrationFlow - 這是一個包含 Groovy DSL 的過載工廠方法的類。

對於將 IntegrationFlow 定義為 lambda 表示式,我們通常不需要 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() 變體。

許多其他場景需要從資料來源(例如 JdbcPollingChannelAdapterJmsInboundGateway 或只是一個現有的 MessageChannel)啟動一個 IntegrationFlow。為此,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' }
            }
}