領先一步
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,然後註冊您想要的任何Converter(如有必要,包括您自己的自定義實現)。在 Spring Integration 中,該 ConversionService 有兩個使用的地方。對於即時轉換,您可以向 <channel> 元素新增一個“datatype”屬性,並提供您希望在該通道上允許的 Class 的完全限定名。這裡是一個示例
<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 物件,那麼您只需要將 BarToFooConverter 註冊到“integrationConversionService”即可。這個示例還展示了一種更簡潔的方式來註冊 Converter。透過使用新的“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 實現)。任何 Polling Consumer 都可以透過顯式的 <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 出站 Messaging Gateway 的示例,它展示了自定義 HttpMessageConverter 和 URI 佔位符的使用。實際上,URI 中被替換的值是 SpEL 在執行時對 Message 載荷進行評估的結果
<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 的企業整合模式一書中描述的更多模式的支援。
透過在 Application Context 中啟用訊息歷史,每個 Message 都將新增一個頭。該頭會記錄所有遍歷過的元件,包括每個通道和端點的名稱以及遍歷的時間戳。對於非同步互動和可能跨越多個執行緒的流很常見的訊息應用程式,監控和審計可能是一個主要挑戰。即使只在開發時啟用,這個簡單的頭對於解決這個挑戰也極其有用。切換這個特性很簡單;只需在配置中新增或刪除 <message-history> 元素即可。預設情況下,它會跟蹤每個通道和端點的歷史,但這可以透過簡單的名稱模式進行微調
<message-history tracked-components="*Service, foo*"/>
訊息儲存提供了一種方法來持久化訊息,用於任何可能需要太長時間才能在單個事務中完成的過程。例如,透過使用新的基於 MessageStore 的訊息通道,您可以擁有緩衝功能
<aggregator input-channel="in" ref="aggregator"
message-store="messageStore" output-channel="out"/>
<int-jdbc:message-store id="messageStore" data-source="dataSource"/>
保管條模式背後的想法是,您可以將訊息載荷換成“保管條”,反之亦然。這允許您在跨通道傳送訊息時減少頻寬和/或避免潛在的安全問題。您可以將其視為“按引用傳遞”,而不是典型的“按值傳遞”語義。我們的實現直接構建在我們剛才提到的訊息儲存支援之上。一對“claim-check-in”和“claim-check-out”轉換器應該共享對同一個訊息儲存的引用。為了方便起見,首先會考慮一個名為“messageStore”的單個 bean。如果需要,您可以透過“message-store”屬性提供一個顯式引用。
<claim-check-in input-channel="payloadsIn" output-channel="ticketsOut"/>
<claim-check-out input-channel="ticketsIn" output-channel="payloadsOut"/>
控制匯流排允許您使用訊息傳遞來管理和監控端點和通道。事實上,這是一個相當通用的機制,您可以在其中傳送一條訊息,該訊息的載荷實際上是一個 SpEL 表示式,用於對整合應用程式中的某個元件進行評估。例如,您可以向控制匯流排的輸入通道傳送載荷為“@somePoller.stop()”的訊息。為了啟用此功能,只需新增元素
<control-bus input-channel="controlChannel"/>
我們在 Spring Integration 2.0 中添加了幾個新的通道介面卡和訊息閘道器。這裡不再提供每個示例配置,對於那些文件中已經很好地涵蓋的,我將簡單地提供 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 Connection 例項
<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 之間提供了一個很好的中間地帶。
這些對稱轉換器可以將載荷物件與 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"/>
這些對稱轉換器可以將載荷物件與 JSON 相互轉換。它們使用 Jackson 庫,並且如果需要自定義行為,可以引用 'object-mapper'。
<object-to-json-transformer input-channel="objectsIn" output-channel="jsonOut"/>
<json-to-object-transformer input-channel="jsonIn" output-channel="objectsOut"/>
這些對稱轉換器可以將載荷物件與位元組陣列相互轉換。雖然在 2.0 中並非全新,但這些轉換器現在委託給一對新的策略介面。預設策略是標準的 Java 序列化。但是,您可以選擇提供一個“serializer”(或用於反序列化轉換器的“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