先人一步
VMware 提供培訓和認證,助您快速提升。
瞭解更多我們很高興宣佈,用於 Spring Integration 的 Java DSL 擴充套件的**第二個里程碑版本**已經發布!
構件 org.springframework.integration:spring-integration-java-dsl:1.0.0.M2
可從 Spring IO 里程碑倉庫獲取。
里程碑 2 包含了一些錯誤修復、一些新特性和進一步改進。
感謝所有嘗試了里程碑 1、提供了反饋、提出了問題並分享了想法的人們。
以下是自 里程碑 1 以來的主要變更摘要
Lambda 處理器
正如您可能已經注意到的,使用 Java 8 Lambdas 是使這個 DSL 方便易讀的強大工具。我們收到的一個社群請求是允許為 .handle()
EIP 方法宣告一個 Lambda,而不是必須宣告一個 POJO 並將其用作方法呼叫。但一個擔憂是不要丟失“執行時型別轉換”。然而,您無法獲取 Lambda 的泛型型別。經過一些調查,我們透過新增一個 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 的方法變體,最後一個引數將封裝到帶有 ConversionService
的 LambdaMessageProcessor
中。訊息的 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
定義中使用它們。然而,如果內聯物件尚未定義為 bean,DSL 解析器會負責處理它們的 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,我們可以繼續對任何終端系統介面卡(例如 MarshallingWebServiceInboundGateway
)使用通用的 bean 定義(@Bean
),但 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
方法鏈更具可讀性。
在我們將精力投入到其他工廠之前,我們正在徵集社群對這些名稱空間工廠的反饋;我們也很希望瞭解接下來我們應該優先支援哪些介面卡/閘道器。
請確保您的 classpath 中有具體的 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 定義,應用程式上下文無法自動為使用 channel 的 bean 宣告 dependsOn
,而且從另一方面來說,我們根本沒有宣告 MessageChannel
bean,我們只有一個選擇就是依賴於 IntegrationFlow
bean。
因此,您可以選擇顯式宣告 MessageChannel
bean,或者在宣告隱式 channel 的下游 IntegrationFlow
的相應 IntegrationFlow
bean 定義上使用 @DependsOn
。
總結
請參閱上面提到的參考手冊以獲取更多資訊。並檢視 [網路研討會回放:Spring Integration 4.0 - 新領域] (https://springframework.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 即將到來
請儘快預訂 9 月 8-11 日在德克薩斯州達拉斯舉行的 SpringOne2GX 的席位。這絕對是第一手瞭解最新動態並提供直接反饋的最佳機會。預計今年將有許多重要的新公告。我們預計將有幾個深入的 Spring Integration 會議。