搶先一步
VMware 提供培訓和認證,以加速您的進展。
了解更多我們很高興宣布發布 Spring Integration 的 Java DSL 擴充功能的第二個里程碑!
org.springframework.integration:spring-integration-java-dsl:1.0.0.M2
artifact 可從 Spring IO 里程碑儲存庫 取得。
里程碑 2 包含數個錯誤修正、一些新功能和進一步的改進。
感謝所有嘗試過里程碑 1、提供意見反應、提出問題並分享想法的人。
以下是自 里程碑 1 以來的主要變更摘要
Lambda 處理器
您可能已經注意到,使用 Java 8 Lambdas 是使此 DSL 方便且易於閱讀的強大工具。 我們收到的一個社群請求是允許為 .handle()
EIP 方法宣告 Lambda,而不是必須宣告 POJO 並將其用作方法調用。 但一個顧慮是不要失去「運行時類型轉換」。 但是,您無法取得 Lambdas 的泛型類型。 經過一番調查,我們透過新增 type
參數找到了解決方案。 因此,已將數個新方法新增至 IntegrationFlowBuilder
<P> IntegrationFlowBuilder handle(GenericHandler<P> handler)
<P> IntegrationFlowBuilder handle(GenericHandler<P> handler,
EndpointConfigurer<GenericEndpointSpec<ServiceActivatingHandler>> endpointConfigurer)
<P> IntegrationFlowBuilder handle(Class<P> payloadType, GenericHandler<P> handler)
<P> IntegrationFlowBuilder handle(Class<P> payloadType, GenericHandler<P> handler,
EndpointConfigurer<GenericEndpointSpec<ServiceActivatingHandler>> endpointConfigurer)
如果您使用帶有顯式 payloadType
參數且 handler
是 Lambda 的方法變體,則最後一個參數將是 LambdaMessageProcessor
的包裝函式,並帶有 ConversionService
。 並且訊息 payload
將在運行時轉換為適當的 type
。 這樣,我們就可以實現更好的鬆散耦合。 這是一個簡單的範例來示範
@Bean
public IntegrationFlow integerFlow() {
return IntegrationFlows.from("input")
.<byte[], String>transform(p - > new String(p, "UTF-8"))
.handle(Integer.class, (p, h) -> p * 2)
.get();
}
ConversionService
可防止 ClassCastException: String cannot be cast to Integer
。
相同的附加類型引數已新增至其他帶有 Lambdas 的 EIP 方法:.transform()
、.filter()
、.split()
等。
轉換器工廠
已新增方便、流暢的 Transformers
工廠,以用作 .transform()
EIP 方法中的內聯目標物件定義
@Bean
public IntegrationFlow transformFlow() {
return IntegrationFlows.from("input")
.transform(Transformers.xpath("/root/myJson", XPathEvaluationType.STRING_RESULT))
.transform(Transformers.fromJson(MyPojo.class))
.transform(Transformers.serializer())
.get();
}
它可以避免使用 setter 進行不方便的編碼,並使流程定義更加直接。 請注意,Transformers
可用於將目標 Transformer
宣告為 @Bean
,並再次從 IntegrationFlow
定義中使用它們。 儘管如此,如果尚未將 DSL 解析器定義為 bean,則它會處理內聯物件的 bean 宣告。
.gateway() EIP 方法
由於 IntegrationFlow
定義看起來類似於 Spring Integration XML 中的 <chain>
,因此我們引入了 .gateway()
EIP 方法,該方法的作用與 <chain>
中的 <gateway>
相同 - 將訊息傳送到某些其他訊息流程的 requestChannel
,並等待其 replyChannel
或預設的 TemporaryReplyChannel
的結果
@Bean
@DependsOn("gatewayRequestFlow")
public IntegrationFlow gatewayFlow() {
return IntegrationFlows.from("gatewayInput")
.gateway("gatewayRequest", g -> g.errorChannel("gatewayError").replyTimeout(10L))
.get();
}
@Bean
public IntegrationFlow gatewayRequestFlow() {
return IntegrationFlows.from("gatewayRequest")
.filter("foo"::equals, f -> f.throwExceptionOnRejection(true))
.<String, String>transform(String::toUpperCase)
.get();
}
特定協定的介面卡
當然,Spring Integration 的大部分價值是由於與某些外部系統的互動提供的,其中通訊協定介面卡提供了該功能。 借助 Spring Integration Java DSL,我們可以繼續將泛型 bean 定義 (@Bean
) 用於任何終端系統介面卡(例如 MarshallingWebServiceInboundGateway
),但 DSL 的目的是提供更高等級的 API,以類似於 Spring Integration XML 設定提供的方式宣告元件。
由於您現在熟悉我們的 Builder
和 Lambda
功能,因此我們以這些技術為基礎。 已引入帶有一組靜態方法的類別,以委派給某些底層 IntegrationComponentSpec<S, P>
實作。 這些類別可以被視為「命名空間工廠」,因為它們在具體通訊協定特定的 Spring Integration 模組中扮演與 XML 命名空間相同的角色。 目前,Spring Integration Java DSL 僅支援 Amqp
和 Jms
命名空間工廠
@Bean
public IntegrationFlow amqpFlow() {
return IntegrationFlows.from(Amqp.inboundGateway(this.rabbitConnectionFactory, queue()))
.transform("hello "::concat)
.transform(String.class, String::toUpperCase)
.get();
}
@Bean
public IntegrationFlow amqpOutboundFlow() {
return IntegrationFlows.from("amqpOutboundInput")
.handle(Amqp.outboundAdapter(this.amqpTemplate).routingKeyExpression("headers.routingKey"))
.get();
}
@Bean
public IntegrationFlow jmsInboundFlow() {
return IntegrationFlows
.from(Jms.inboundAdapter(this.jmsConnectionFactory)
.configureJmsTemplate(t ->
t.deliveryPersistent(true)
.jmsMessageConverter(myMessageConverter()))
.destination("jmsInbound"))
.<String, String>transform(String::toUpperCase)
.channel(this.jmsOutboundInboundReplyChannel())
.get();
}
@Bean
public IntegrationFlow jmsOutboundGatewayFlow() {
return IntegrationFlows.from("jmsOutboundGatewayChannel")
.handle(Jms.outboundGateway(this.jmsConnectionFactory)
.replyContainer(c ->
c.concurrentConsumers(3)
.sessionTransacted(true))
.requestDestination("jmsPipelineTest"))
.get();
}
我們在此顯示命名空間工廠的使用,作為內聯介面卡宣告,但是它們可以用於 @Bean
定義,以使 IntegrationFlow
方法鏈更具可讀性。
在我們花費精力在其他命名空間工廠之前,我們正在徵求社群對這些命名空間工廠的回饋;我們也希望對我們接下來應該支援哪些介面卡/閘道進行優先排序。
請確保在類別路徑上具有具體的 spring-integration-[PROTOCOL].jar
及其所需的依賴項,因為 spring-integration-java-dsl
將它們宣告為 optional
以避免不必要的終端應用程式開銷。
DSL 解析器變更
儘管如此,此 M2 版本的總體目的是解決 DSL 解析器的錯誤位置這一關鍵問題。 現在它已從 IntegrationConfigurationBeanFactoryPostProcessor
移至 IntegrationFlowBeanPostProcessor
,並且 Spring Integration Java DSL 不再影響應用程式內容 - 它只是遵循標準的 Spring bean 定義生命週期。 您可能需要對現有的 DSL 應用程式進行一些變更才能使用此版本。
在大多數情況下,這僅限於 channel auto-declaration
,當我們不定義顯式的 MessageChannel
bean 定義時,而是從整合元件引用它。 如果您在上面的 .gateway()
範例中注意到,我們使用了 @DependsOn
註釋。 這是因為 bean 會在 @Configuration
類別中宣告時一個一個地註冊和初始化。 由於我們不對 MessageChannel
使用 bean 定義,因此應用程式內容無法自動宣告 bean 的 dependsOn
,該 bean 使用通道,並且從另一方面來說,我們根本不宣告 MessageChannel
bean,我們只有一種選擇來依賴 IntegrationFlow
bean。
因此,您可以選擇顯式宣告 MessageChannel
bean,或者在下游 IntegrationFlow
的適當 IntegrationFlow
bean 定義上使用 @DependsOn
,該下游 IntegrationFlow
宣告隱式通道。
總結
請參閱上面提到的參考手冊以獲取更多資訊。 並查看[網路研討會重播:Spring Integration 4.0 - 新的邊界] (https://spring.dev.org.tw/blog/2014/05/15/webinar-replay-spring-integration-4-0-the-new-frontier),其中 Spring Integration Java DSL 已透過「現場編碼」引入。
與往常一樣:請隨時分享您的想法和回饋:StackOverflow(spring-integration
標籤)、Spring JIRA。
SpringOne 2GX 2014 即將到來
儘早預訂您在 德州達拉斯舉行的 SpringOne2GX 的位置(9 月 8 日至 11 日)。 這絕對是第一手了解所有資訊並提供直接回饋的最佳機會。 預計今年會有一些重要的新公告。 我們預計將會舉辦一些深入的 Spring-Integration 會議。