領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多我們很高興地宣佈 Spring Integration 2.0 的第一個候選版本!下載 | 參考手冊 | JavaDoc
我想借此機會提供一個通用的“有什麼新內容?”指南。實際上,新的功能和改進太多,無法在一篇文章中全部涵蓋,但我將重點介紹一些亮點。隨著我們越來越接近 2.0 GA 版本,我們將釋出更多部落格。目前,本文大致基於 Oleg 和我上週在 SpringOne 上的一次演示。該演示主要是透過程式碼演示的,程式碼可在我們的Git 倉庫中找到。
為了提供一些結構,我將按幾個類別介紹這些功能……
Spring Integration 2.0 直接構建在 Spring 3.0 之上。事實上,RC1 版本是基於上週釋出的 Spring 3.0.5 構建的。在這裡,我們將介紹底層框架的這一重要升級所帶來的幾個最值得注意的功能。
現在,您可以在 Spring Integration 核心名稱空間中的 transformer、router、filter、splitter、aggregator、service-activator 以及更多元素中使用 SpEL 表示式。例如,如果您可以基於載荷物件中的簡單屬性評估 Filter 規則,只需執行以下操作:
<filter input-channel="numbers" expression="payload > 0" output-channel="positives"/>
在許多情況下,'expression' 屬性可以取代 'ref' 和 'method' 以及 ref 指向的 POJO。另一方面,即使您需要執行 Spring 上下文中某個 bean 的方法,簡單的 'method' 屬性可能也不夠。例如,您可能需要控制傳遞給方法的引數不止一個。雖然方法引數上的 @Payload 和 @Header 註釋提供了一種選擇,但有時最好將這些細節保留在配置中而不是程式碼中。以下是一個使用 SpEL BeanResolver 策略而不是 'ref' 的示例:
<router input-channel="accounts"
expression="@accountService.getAccountType(payload.accountId, payload.address.country)"/>
您可以定義一個名為 "integrationConversionService" 的 ConversionService bean,然後註冊您想要的任何 Converters(如果需要,包括您自己的自定義實現)。Spring Integration 中 ConversionService 的使用有兩個地方。對於即時轉換,您可以在 <channel> 元素中新增 "datatype" 屬性,並提供您希望在該通道上允許的類的完全限定名稱。以下是一個示例:
<channel id="datatypeChannel" datatype="example.Foo"/>
<beans:bean id="integrationConversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<beans:property name="converters">
<beans:bean class="conversion.StringToFooConverter"/>
</beans:property>
</beans:bean>
在評估 SpEL 表示式時,"integrationConversionService" 發揮著重要作用。每個表示式都針對一個 EvaluationContext 進行評估,該上下文了解 "integrationConversionService"。在 Spring Integration 中,我們依賴 SpEL 來處理所有方法呼叫(不僅在使用 'expression' 屬性時,甚至對於 'ref' 和 'method' 配置也是如此)。這意味著您可以利用從 Message 例項繫結到方法呼叫的值的執行時型別轉換。例如,如果您呼叫 FooService 但在 Message 載荷中傳遞了 Bar 物件,那麼您只需向 "integrationConversionService" 註冊一個 BarToFooConverter。此示例還展示了一種更簡潔的註冊 Converters 的方式。透過使用透過新的 'converter' 元素提供的名稱空間支援,您甚至不需要顯式定義 "integrationConversionService" bean:
<!-- FooService.process(Foo) will be invoked, even though the Message payload is a Bar instance -->
<service-activator input-channel="in" ref="fooService" method="process" output-channel="out"/>
<converter>
<beans:bean class="example.BarToFooConverter"/>
</converter>
Spring Integration 1.0 有自己的 TaskScheduler 實現以及基於間隔和 cron 的 Trigger 實現。現在 Spring 3.0 提供了 TaskScheduler 和 Trigger,我們可以依賴它們。事實上,我們能夠從 Spring Integration 中移除大量程式碼,並將其中一部分貢獻回底層框架(例如,輕量級的 CronTrigger 實現)。任何輪詢消費者都可以使用顯式的 <poller> 子元素進行配置(否則,它將依賴於單個預設的 poller 配置)。這些 poller 元素接受以下屬性之一:“fixed-delay”、“fixed-rate”或“cron”。事實上,您甚至可以提供 Spring 的 Trigger 介面的自定義實現,然後將 'trigger' 屬性用作引用。以下是一個帶有 cron 表示式的 poller 示例:
<file:inbound-channel-adapter directory="/some/path">
<poller cron="*/10 * 9-17 * * MON-FRI"/>
</file:inbound-channel-adapter>
我們的出站 HTTP 介面卡現在委託給 Spring 的 RestTemplate 來執行 HTTP 請求和處理其響應。這意味著 HttpMessageConverter 策略起著核心作用。我們預設啟用了幾種轉換器,但您可以完全自定義列表和/或新增自己的實現。我們實際上在 HTTP 入站介面卡中也使用了相同的 HttpMessageConverter 策略。利用 RestTemplate 的另一個很好的功能是 URI 佔位符的使用。以下 HTTP 出站訊息閘道器的示例演示了自定義 HttpMessageConverter 和 URI 佔位符的使用。事實上,在 URI 中替換的值是執行時對 Message 載荷進行 SpEL 評估的結果:
<http:outbound-gateway id="trafficService"
url="http://example/traffic/{zipCode}"
request-channel="requestChannel"
reply-channel="responseChannel"
http-method="GET"
message-converters="trafficConverter"
expected-response-type="example.Traffic">
<http:uri-variable name="zipCode" expression="payload.address.zipcode"/>
</http:outbound-gateway>
在 2.0 版本中,我們還增加了對 Hohpe 和 Woolf 的 企業整合模式 書籍中描述的更多模式的支援。
透過在應用程式上下文中啟用訊息歷史記錄,將向每條訊息新增一個頭。該頭跟蹤所有遍歷的元件,包括每個通道和端點的名稱以及遍歷的時間戳。對於非同步互動和可能跨越多個執行緒的流程很常見的訊息傳遞應用程式,監控和審計可能是一個重大挑戰。這個簡單的頭對於解決這個挑戰非常有用,即使它只在開發時啟用。切換該功能非常簡單;只需在配置中新增或刪除 <message-history> 元素。預設情況下,它將跟蹤每個通道和端點的歷史記錄,但可以透過簡單的名稱模式進行微調:
<message-history tracked-components="*Service, foo*"/>
Message Store 提供了一種持久化訊息的方法,用於任何可能在單個事務中花費過長時間處理的過程。例如,透過使用新的 MessageStore 後備 Message Channel,您可以實現緩衝:
<aggregator input-channel="in" ref="aggregator"
message-store="messageStore" output-channel="out"/>
<int-jdbc:message-store id="messageStore" data-source="dataSource"/>
Claim Check 模式背後的想法是,您可以將 Message 載荷替換為“claim ticket”,反之亦然。這允許您減少頻寬和/或避免在跨通道傳送訊息時出現潛在的安全問題。您可以將其視為“按引用傳遞”,而不是典型的“按值傳遞”語義。我們的實現直接構建在我們上面提到的 Message Store 支援之上。“claim-check-in”和“claim-check-out”轉換器對應該共享對同一 Message Store 的引用。為了方便起見,將首先考慮一個名為“messageStore”的單個 bean。如有必要,您可以透過 'message-store' 屬性提供顯式引用:
<claim-check-in input-channel="payloadsIn" output-channel="ticketsOut"/>
<claim-check-out input-channel="ticketsIn" output-channel="payloadsOut"/>
Control Bus 允許您使用訊息來管理和監視端點和通道。事實上,這是一個相當通用的機制,您可以透過它傳送一個 Message,其載荷實際上是一個 SpEL 表示式,用於在您的整合應用程式中的某個元件上進行評估。例如,您可以將 "@somePoller.stop()" 的載荷傳送到 Control Bus 的輸入通道。為了啟用此功能,只需新增元素:
<control-bus input-channel="controlChannel"/>
我們在 Spring Integration 2.0 中添加了幾個新的 Channel Adapters 和 Messaging Gateways。為了避免為其中一些重複配置示例(它們在文件中已經講得很清楚),我將簡單地提供指向 Spring Integration 參考手冊相關部分的連結。
還有一些其他功能將在 GA 參考手冊中介紹,但我在此提供簡要說明和/或相關連結。FTP 和 SFTP 介面卡在 Josh Long 的 這篇最新博文 中得到了詳細介紹。
我們還增加了 RSS/Atom Feed 讀取支援。以下是一個示例:
<feed:inbound-channel-adapter channel="newsChannel" url="http://example/news/rss.xml"/>
以及大家最喜歡的:Twitter 介面卡。我們支援入站和出站狀態更新以及直接訊息。這是一個簡單的示例。如您所見,它允許配置一個支援 OAuth 的 Twitter 連線例項:
<twitter:outbound-update-channel-adapter channel="tweets"
twitter-connection="twitterConnection"/>
<twitter:twitter-connection id="twitterConnection"
consumer-key="${twitter.oauth.consumerKey}"
consumer-secret="${twitter.oauth.consumerSecret}"
access-token="${twitter.oauth.accessToken}"
access-token-secret="${twitter.oauth.accessTokenSecret}"/>
與上面顯示的 SpEL 示例一樣,您實際上可以使用 Groovy 指令碼來實現任何 transformer、filter、router、splitter 等。指令碼可以非常簡單,並且可以利用在執行時繫結到指令碼執行上下文的 'payload' 和 'headers'。例如,以下 Groovy 指令碼可以定義為 'LengthRouter.groovy':
return payload.length() > 100 ? 'long' : 'short'
然後,您可以從 router 元素(或任何其他核心元素型別)中引用它。您可以提供一個 'refresh-check-delay',以便在執行時可以拾取指令碼中的更改:
<router input-channel="strings">
<int-groovy:script location="example/LengthRouter.groovy" refresh-check-delay="10000"/>
</router>
當然,您可以在 Groovy 指令碼中做更多的事情。總的來說,Groovy 指令碼選項在 SpEL 和 POJO 之間提供了一個很好的中間地帶。
這些對稱的 transformer 將載荷物件轉換為/從 Map,其中 Map 中的鍵可以透過 SpEL 持有“平面”屬性路徑(例如 'customer.address.city')。
<object-to-map-transformer input-channel="objectsIn" output-channel="mapsOut"/>
<map-to-object-transformer input-channel="mapsIn" output-channel="objectsOut"/>
這些對稱的 transformer 將載荷物件轉換為/從 JSON。它們使用 Jackson 庫,如果您需要自定義行為,可以引用 'object-mapper'。
<object-to-json-transformer input-channel="objectsIn" output-channel="jsonOut"/>
<json-to-object-transformer input-channel="jsonIn" output-channel="objectsOut"/>
這些對稱的 transformer 將載荷物件轉換為/從位元組陣列。雖然在 2.0 版本中並不全是新的,但這些 transformer 現在委託給一對新的策略介面。預設策略是標準的 Java 序列化。但是,您可以選擇提供一個 'serializer'(或反序列化 transformer 的 'deserializer')屬性值來引用任何 Serializer(或 Deserializer)實現。這些是 Spring 3.0.5 中提供的新策略介面。這些相同的策略也在 JDBC MessageStore 和 TCP/UDP 介面卡中使用。同樣,隨著 Spring Data 專案的發展,您可以期待看到許多新實現。
<payload-serializing-transformer input-channel="objectsIn" output-channel="bytesOut"
serializer="someCustomSerializer"/>
<payload-deserializing-transformer input-channel="bytesIn" output-channel="objectsOut"
deserializer="someCustomDeserializer">
最後,我想指出的是,最新版本的 SpringSource Tool Suite 中包含一個令人驚歎的 Spring Integration 新視覺化編輯器。如果您還沒有使用 STS 2.5.0,您真的應該 立即下載!以下是我們“Cafe”示例在 STS 視覺化編輯器中的截圖: 
像往常一樣,我的“簡短”博文變成了一個史詩。好訊息是,即使是看起來很長的功能列表,也只是觸及了 Spring Integration 2.0 所提供功能的表面。請下載 RC1 並試用一下。一如既往,我們非常期待社群的反饋。希望您喜歡 RC1,並且透過您在 論壇 和 問題跟蹤器 中的貢獻,我們可以確保 2.0 GA 更好。
謝謝! -Mark