Spring Integration 1.0.3 示例:只需新增 OSGi

工程 | Oleg Zhurakousky | 2009 年 7 月 28 日 | ...

介紹

上週,Mark Fisher 向您介紹了隨 Spring Integration 1.0.3 新版本釋出的重組和簡化的 Spring Integration 示例,迄今為止,反饋非常積極。除了重組和簡化現有示例外,我們還引入了一些新示例,旨在展示在基於 OSGi 的平臺上執行 Spring Integration 的一些優勢。在這篇部落格中,我們將使用一個非常簡單但功能強大的示例來探討 Spring Integration 和 OSGi 結合使用以解決當今企業動態特性的一些優勢。

Spring Integration 是一個基於POJO的輕量級、可嵌入的訊息傳遞框架,它採用松耦合程式設計模型,旨在根據企業整合模式簡化異構系統整合,而無需獨立的類似ESB的引擎或專有的開發和部署環境。另一方面,OSGi是一種允許人們使用獨立的OSGi Bundle模組來構建松耦合系統的正規化。從一組獨立開發的模組構建系統可能並不是一個新正規化,我們已經這樣做了(希望如此)多年。話雖如此,OSGi模組化真正的好處並非來自於其靜態打包模型,而是來自於理解其部署和執行時動態性以及它如何很好地應對當今業務流程的動態性。

那麼,讓我們透過一個簡單的例子來看看基於訊息交換的整合和OSGi的動態性如何相互補充,從而實現非常強大和動態的系統。

Spring Integration 的示例隨 Spring Integration 分發。您也可以從此處獨立下載它們。為簡單起見,這些示例是作為SpringSource Tool Suite (STS) 專案開發的,同時利用 dm Server 工具與SpringSource dm Server(一個基於OSGi和Spring的企業Java平臺)進行快速整合。然而,作為符合OSGi標準的專案,這些示例可以在任何配置正確的OSGi平臺上正常執行。

環境

首先,讓我們確保我們有一個配置正確的開發/部署環境。

要配置STS/dm Server環境,請按照以下步驟操作

此處下載並解壓STS 從此處下載並解壓SpringSource dm Server

Spring Source Tool Suite v2.1.x 將預配置 SpringSource dm Server,但瞭解如何手動配置仍然有幫助。
開啟STS並配置dm Server:開啟Server View -> 右鍵單擊Server檢視中的空白處 -> 新建(New) -> 伺服器(Server)

picture-14

選擇 SpringSource -> SpringSource dm Server v1.0 -> 下一步(Next)

指向您安裝伺服器的目錄

picture-22

點選完成(Finish)

picture-3

您現在已經在STS環境中配置了SpringSource dm Server。啟動dm Server並確保它成功啟動且沒有錯誤。

假設您已經下載了Spring Integration示例,所以讓我們使用STS/Eclipse提供的“將現有專案匯入工作區”嚮導將兩個示例專案匯入工作區。檔案(File) -> 匯入(Import) -> 通用(General) -> 現有專案到工作區(Existing Projects into Workspace) -> 下一步(Next) 瀏覽到示例目錄的位置並選擇osgi-inboundosgi-outbound專案

picture-51

點選完成(Finish) 您應該會看到兩個有錯誤的專案。

picture-4

這些錯誤是預料之中的,因為我們的專案不知道dm Server目標執行時,而我們的dm Server目標執行時也不知道Spring Integration bundle。讓我們一次解決一個問題。首先,透過將Spring Integration及其依賴的bundle部署到dm Server的倉庫中,讓dm Server知道Spring Integration。這是一個非常簡單的過程。將org.springframework.integration-1.0.3.RELEASE.jarorg.springframework.integration.file-1.0.3.RELEASE.jar (我們的示例依賴的兩個bundle)複製到dm Server的repository/bundles/usr 目錄中。然後在STS的Server檢視中雙擊dm Server例項 -> 點選Repository選項卡,在右上角您會找到一個Refresh按鈕。點選它,您應該會在dm Server的倉庫中看到這兩個bundle。

picture-6

現在我們需要讓我們的bundle專案知道我們新的目標執行時。右鍵單擊每個專案 -> 屬性(Properties) -> 目標執行時(Target Runtimes) -> SpringSource dm Server (Runtime) v1.0

picture-7

現在所有錯誤都應該消失了。您已準備好測試這些示例

示例

這兩個示例基於非常簡單且熟悉的生產者/消費者概念。第一個bundle osgi-inbound 是一個生產者,它將允許您生成一條訊息,該訊息將被髮送到一個訊息通道。第二個bundle osgi-outbound 是一個消費者,它將消費由 osgi-inbound bundle放置在通道上的訊息,並將訊息寫入檔案。

右鍵單擊伺服器例項 -> 啟動(Start)來啟動dm Server

透過簡單地將osgi-inbound專案拖放到dm Server例項上來部署osgi-inbound。幾秒鐘內您應該會看到成功的啟動訊息

[2009-07-27 21:56:49.040] onnection(5)-172.16.12.1 <SPDE0010I> Deployment of 'org.springframework.integration.samples.osgi.inbound'
version '1.0.3' completed.

然後對osgi-outbound bundle執行相同的操作

[2009-07-27 21:58:45.220] onnection(8)-172.16.12.1 <SPDE0010I> Deployment of 'org.springframework.integration.samples.osgi.outbound'
version '1.0.3' completed.

現在您已經準備好測試這些bundle提供的功能。為了使其更有趣,我們透過OSGi控制檯啟用了命令列介面(CLI),它允許您透過提供命令訊息和您希望訊息寫入的檔名來與osgi-inbound bundle互動。您可以透過以下方式連線到OSGi控制檯

telnet localhost 2401

或者您可以使用Server檢視的Server Console選項卡並鍵入

siSend "Hello World" hello.txt

然後點選執行(Execute)

您將看到以下內容

picture-9

去驗證您的訊息是否已寫入檔案。

這個非常簡單且微不足道的概念展示了基於Spring Integration提供的訊息模型的兩個系統之間的松耦合整合。然而,在現實世界中,在嘗試整合兩個系統時我們必須面對的問題之一是這些系統的獨立生命週期,其中其行為的變化新系統的新增和/或舊系統的壽命終止是正常現象。通常,此類更改不僅需要程式碼更改,還需要在完成伺服器重啟後重新部署整個單體(例如EAR、WAR)應用程式。Spring Integration的POJO程式設計模型非常適合處理這些系統的松耦合特性,其中一個系統的更改很少會影響另一個系統。然而,其生命週期動態性如何呢?讓我們假設(在我們的小示例範圍內)關於檔案寫入位置或方式的要求已更改。“位置”和“方式”都是osgi-outbound bundle的責任。在正常情況下,對osgi-outbound bundle功能的任何更改都需要完全刷新系統(即重新部署整個系統和重新啟動伺服器)。當您的系統只包含兩個bundle時,這可能不是一個大問題。但是如果超過兩個呢?您是否準備好僅僅因為訊息寫入的目錄發生了變化,或者引入了一個應該記錄每條傳入訊息的新子系統,就重建和重新部署整個打包為WAR或EAR的系統?

這正是OSGi及其服務層,最重要的是OSGi服務動態性提供巨大幫助的地方。因此,讓我們以上述示例需求為例,看看它們如何透過擴充套件當前示例來實現。首先,讓我們回顧一下 osgi-inbound bundle 的應用上下文配置

<osgi:service id="inboundService" ref="inboundChannel"
interface="org.springframework.integration.channel.SubscribableChannel"/>

<integration:publish-subscribe-channel id="inboundChannel"/>

<integration:gateway id="inboundGateway"
service-interface="org.springframework.integration.samples.osgi.inbound.InboundGateway"
default-request-channel="inboundChannel"/>

如您所見,這是一個非常簡單的配置,它定義了一個閘道器代理,允許以 POJO 的方式傳送訊息,該訊息將存入配置為釋出-訂閱通道的入站通道。然而,更令人感興趣的是,該通道已透過元素作為服務匯出到 OSGi 服務登錄檔,從而允許當前和未來 bundle 之間實現更松耦合但動態的協作模型。

我們再來回顧一下 osgi-outbound bundle 的應用程式上下文配置。

<osgi:reference id="filesIn"
interface="org.springframework.integration.channel.SubscribableChannel"/>

<file:outbound-gateway id="filesOut"
request-channel="filesIn"
directory="${java.io.tmpdir}/spring-integration-samples/output"
delete-source-files="true"/>

這個bundle的目標是:一旦osgi-inbound bundle啟動,就動態訂閱它釋出的通道,並將訊息寫入由元素配置的目錄中的檔案,從而實現OSGi服務層提供的動態性。如您在此配置中看到的,由osgi-inbound bundle匯出的“inboundChannel”OSGi服務現在透過元素匯入。現在,由OSGi服務前端的入站通道已準備好在執行時動態接受和/或失去訂閱者。由於OSGi服務的動態性,我們還可以更新配置或完全重新設計/重新實現osgi-outbound bundle,而不會影響系統的生產部分(osgi-inbound)。那麼,讓我們繼續修改檔案寫入的目錄(確保dm Server仍在執行……事實上,在這篇部落格期間就不要停止它了)

開啟 osgi-outbound 專案 -> src -> META-INF -> spring -> osgi-outbound.xml 並向 'directory' 配置新增一個子目錄(在此示例中為 'foo') picture-8 儲存檔案。幾秒鐘後,您將看到您的 osgi-outbound bundle 已重新部署。開啟 OSGi 或伺服器控制檯,像之前一樣傳送另一條訊息,看看新檔案是否已寫入您剛指定的目錄。希望如此 ;)

結論

請記住,儘管在這個簡單的例子中我們只處理兩個bundle,但這些型別的生產者/消費者bundle本身可以是您系統其他部分的閘道器,而這些部分天生就是動態的。舉例來說,假設您想收到關於檔案被寫入的電子郵件通知。使用SI和OSGi,您唯一需要做的就是建立另一個bundle來代表您子系統的該部分作為osgi-inbound bundle釋出的通道服務的消費者,當您不需要它時——透過停止或取消部署此消費者來取消訂閱,而不會影響系統的其餘部分。事實上,您可以嘗試開發另一個bundle作為osgi-inbound消費者,或者發揮您的想象力,開發另一個bundle來處理由osgi-outbound bundle寫入的檔案。

更多想法和更復雜的例子,您可能還會喜歡閱讀Spring Integration團隊成員Iwein Fuld的這篇文章

最重要的是——整合快樂!!!

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有