[转载]使用 Apache Geronimo 和 POJO 构建 SOA 框架
使用 Apache Geronimo 和 POJO 構建 SOA 框架
在不考慮庫和框架強制執行的應用程序編程接口 (API) 約束的情況下進行軟件開發,是一個非常誘人主張。它使許多人接受了普通舊式 Java? 對象(Plain Old Java? Object,POJO)編程的范例 —— 能夠在 Java 平臺上開發軟件,而無需使用多余的接口或第三方 API。Apache Geronimo 框架為構建復雜應用程序和服務的 POJO 開發提供了一個可靠的基礎設施。本文介紹 Geronimo 框架的一些組件和技巧,用于通過 POJO 策略來實現成功的、面向服務的開發。
面向服務的架構 (SOA) 和面向服務的編程 是兩個術語,指軟件工程的風格,它們將業務邏輯封裝為模塊化服務。這些服務以動態運行時環境為目標,在該環境中,服務提供者和服務消費者之間的關聯是松散 耦合的。松散耦合的服務通常沒有任何編譯時關聯,所以在運行時,您可以動態地將它們鏈接在一起,并允許開發人員根據需要靈活地做出開發決策。除松散耦合之 外,下列概念也是面向服務的環境中的公共概念:
- 粗粒度:服務的粒度是指服務公開給出的功能范圍。細粒度的服務 表示定義一定程度的功能性的公共接口。粗粒度的服務 表示較一般程度的功能性,通常適合于給定的業務領域。
- 位置透明度 (Location transparency):位置透明度是指客戶機在不考慮位置的情況下訪問網絡上的服務。
- 協議獨立性:協議獨立性指客戶機在不考慮通信/網絡協議的情況下訪問服務。
將服務與這些概念綁定在一起是一項艱難的任務。但 POJO 編程可以簡化這一任務。
POJO 簡介
POJO 是無需遵循特定外部接口或第三方 API 的 Java 類。此功能本身就是取消代碼與外部關聯的耦合。去耦的主要好處之一是讓軟件開發人員無需開發輔助任務(如持久性、事務支持和遠程操作)。許多技術消除了組件/類的去耦,并促進了 POJO 編程,包括:
- 注釋是開發工具使用的、并用于生成代碼的元數據,它可以 “裝飾” 一個類或部分類,以支持給定類型的功能或特性,如遠程操作、持久性和框架支持。
- 依賴性注入是構建插入式 組件的技術,對象創建和關聯是從組件移除的,并由容器或匯編組件實現。
- 反射是運行時發現的關于給定類或接口的信息,如方法、字段和構造函數。
每種去耦技術都有其優點和缺點。本文將通過 POJO 編程構建一個簡單的 SOA 框架,它使用反射和 Geronimo 的 GBean 依賴性注入來讓組件去耦。
|
JMX 和 Geronimo
Geronimo 構建在通用的內核基礎上,它使用 Java Management Extensions (JMX) 和稱為 GBean 的托管組件的依賴性注入框架。實際上,Geronimo 中的每件事物(適配器、應用程序和容器等)即是一個 GBean,也以 GBean 為基礎。GBean 與 JMX 和 JMX Managed Beans (MBeans) 共享許多相似點和相同的底層基礎設施。
|
Geronimo 的 GBean 框架
GBean 是 Geronimo 中的托管組件,這些組件共享許多相似點以及與 JMX MBean 的關系,如根據名為 GBeanInfo 的類公開屬性和操作,該類與 JMX 替代物 MBeanInfo 類非常相似。Geronimo 將 MX4J 庫(請參閱本文結尾的 參考資料)用作其 JMX 的實現。
GBean 維護狀態和關聯依賴性,并處理生命周期事件。GBean 可以注冊為其他 GBean 狀態中的相關方。啟動相關 GBean 后,它將通過依賴性注入收到相關 GBean 的引用。GBean 在任何給定的時間可以處于下列七個生命周期狀態之一:
清單 1 給出了一個包含一個屬性(消息)的簡單 GBean。
清單 1. 典型的 GBean
| public class TestGBean implements GBeanLifecycle { private static GBeanInfo GBEAN_INFO = null; static { GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(TestGBean.class); infoFactory.addAttribute("message", String.class, true); infoFactory.addOperation("getMessage"); GBEAN_INFO = infoFactory.getBeanInfo(); } private String message; public String getMessage() { return message; } ... } |
您可以使用 清單 2 中給出的代碼來啟動(激活)和停止 GBean。
清單 2. 啟動典型的 GBean
| ObjectName testGBeanOName = ObjectName.newInstance("jeffhanson.test:ID=test"); GBeanData gBeanData = new GBeanData(testGBeanOName, TestBean.GBEAN_INFO); gBeanData.setAttribute("message", "Hello world"); geronimoKernel.loadGBean(gBeanData, Thread.currentThread(). getContextClassLoader()); geronimoKernel.startGBean(testGBeanOName); ... geronimoKernel.stopGBean(testGBeanOName); geronimoKernel.unloadGBean(testGBeanOName); |
您可以在整個 Geronimo 內核中大量地使用 GBean。
|
Geronimo 內核
Geronimo 內核 是 GBean 的一個框架。使用此框架,您可以建模并構建任何復 雜的系統作為一組 GBean 容器和 GBean 組件,來管理狀態、關系和事件處理。
使用 KernelFactory 類,以編程方式創建 Geronimo 內核是一個非常簡單的過程。清單 3 說明如何通過啟動內核、記錄啟動時間和加載并啟動 servlet GBean 來創建名為 TestGeronimo 的新 Geronimo 內核。
清單 3. 創建一個簡單的 Geronimo 內核
| try { Kernel geronimoKernel = BasicKernelFactory.newInstance(). createKernel("TestGeronimo"); geronimoKernel.boot(); log.debug("Geronimo BootTime: " + geronimoKernel.getBootTime()); // add the servlet GBean ObjectName servletObjName = new ObjectName("jeffhanson.test:ID=MyGBean"); GBeanData servletGBeanData = new GBeanData(servletObjName, GBEAN_INFO); ClassLoader classLoader = getClass().getClassLoader(); geronimoKernel.loadGBean(servletGBeanData, classLoader); geronimoKernel.startGBean(servletObjName); } catch (Exception e) { log.error(e); } |
創建并運行內核后,調用 POJO 服務上的方法就變成了練習使用 Geronimo 內核服務器及其反射功能,如 清單 4 所示。
清單 4. 調用注冊到內核的服務上的調用
| private static Object invokePOJOService(ObjectName serviceObjName, String operationName, String[] params) throws Exception { String[] paramTypes = null; if (params != null && params.length > 0) { paramTypes = new String[params.length]; for (int i = 0; i < params.length; i++) { paramTypes[i] = params[i].getClass().getName(); } } Kernel geronimoKernel = KernelManager.getInstance().getGeronimoKernel(); Object retVal = geronimoKernel.invoke(serviceObjName, operationName, (Object[])params, paramTypes); return retVal; } |
|
Geronimo 中面向服務的 POJO 的可適應框架
本 文中引用的用于 SOA 的 POJO 框架使用 Geronimo 內核實例將 POJO 注冊為 GBean,相關客戶機可以查詢并調用它們,而無需其他接口或 API。框架駐留在多層企業級應用程序環境中的業務層中。服務定位符類負責與內核交互,以查找并注冊(如果需要) 用作服務的 POJO。然后服務定位符類將 POJO 返回到調用它們的業務委派組件。圖 1 說明了框架中組件的關系。
圖 1. 用于 SOA 的 POJO 框架
該框架旨在從客戶機接收 HTTP 請求,然后將請求傳遞到調度程序組件,該組件會發送消息,并將請求分派給業務委派組件。 然后,業務委派組件使用服務定位符找到特定請求的服務。業務委派組件調用該服務,并將任何返回值打包為模型對象。適當的視圖組件將處理模型對象,并返回它作為對客戶機的格式化響應。圖 2 中的順序圖說明了這些步驟。
圖 2. 典型 HTTP 請求和服務調用的往返順序
圖 3 中的類圖說明了框架的類之間的關系。
圖 3. 框架的類之間的關系
|
部署并運行框架
框架駐留在企業級應用程序系統的業務層中。該框架公開一個接收 HTTP 請求的 servlet,并將內容分派給框架進行處理。下一節將闡述簡單的部署過程。
部署框架
您可以將框架的類和企業級應用程序打包在 .war 文件中,將其放置在 geronimo_home/deploy 目錄下。如果此目錄不存在,就創建它。
Geronimo 在啟動時會自動部署 .war 文件。放置在 deploy 目錄中的應用程序是熱加載的,允許 Geronimo 在您做出更改時能夠在運行時重新加載應用程序。這樣使調試應用程序變得非常便利。
測試框架
您可以使用位于 geronimo_home/bin 目錄中的啟動腳本(startup.bat 或 startup.sh)啟動 Geronimo 應用服務器。當調用 Geronimo 啟動腳本時,可以看到 Geronimo 控制臺窗口。部署框架和應用程序后,啟動時的 Geronimo 控制臺窗口包含類似于 清單 5 所示的行,確認 Web 應用程序已經成功啟動。
清單 5. Web 應用程序已經成功啟動的確認
| 0 [main] DEBUG org.apache.geronimo.kernel.basic.BasicKernel - Starting boot 422 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState - GBeanInstanceState for: :role=Kernel State changed from stopped to starting 422 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState - GBeanInstanceState for: :role=Kernel State changed from starting to running 422 [main] DEBUG org.apache.geronimo.kernel.basic.BasicKernel - Booted 640 [main] DEBUG com.jeffhanson.apptier.FrontController - Geronimo BootTime: Sat May 20 18:51:08 MDT 2006 656 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState - GBeanInstanceState for: jeffhanson.test:ID=FrontController State changed from stopped to starting 656 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState - GBeanInstanceState for: jeffhanson.test:ID=FrontController State changed from starting to running |
現在,在 Web 瀏覽器窗口鍵入以下 URL,以激活 HelloWorld 服務上的 setMessage 操作:
http://:/?Action=HelloWorld&Operation=setMessage&Params=Hello+everybody!
當框架處理請求時,控制臺的輸出結果應類似于 清單 6 所示。
清單 6. setMessage 操作處理的輸出結果
| 719 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator - Adding service [HelloWorld] to kernel... 719 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator - Loading GBean: jeffhanson.test:Name=HelloWorld,Type=GenericService 734 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState - GBeanInstanceState for: jeffhanson.test:Name=HelloWorld,Type=GenericService State changed from stopped to starting 734 [main] DEBUG org.apache.geronimo.gbean.runtime.GBeanInstanceState - GBeanInstanceState for: jeffhanson.test:Name=HelloWorld,Type=GenericService State changed from starting to running |
在 Web 瀏覽器窗口中鍵入以下 URL,以激活 HelloWorld 服務上的 sayHello 操作:
http://:/?Action=HelloWorld&Operation=sayHello
當框架處理請求時,控制臺的輸出結果應類似于 清單 7 所示。
清單 7. sayHello 操作處理的輸出結果
| 750 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator - serviceObjName: jeffhanson.test:Name=HelloWorld,Type=GenericService 750 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator - Service [HelloWorld] already in kernel 1156 [main] DEBUG com.jeffhanson.businesstier.ServiceLocator - serviceObjName: jeffhanson.test:Name=HelloWorld,Type=GenericService 1156 [main] INFO com.jeffhanson.businesstier.services.HelloWorld - Hello everybody! |
當 servlet 引擎關閉 servlet,并調用 servlet 上的 destroy 方法時,servlet 會關閉 Geronimo 內核。當 servlet 引擎關閉 servlet 時,您控制臺的輸出結果應類似于 清單 8 所示。
清單 8. servlet 關閉后的輸出結果
| 1156 [main] DEBUG org.apache.geronimo.kernel.basic.BasicKernel - Starting kernel shutdown 1156 [main] DEBUG org.apache.geronimo.kernel.basic.BasicKernel - Kernel shutdown complete |
HelloWorld 類是帶有 setMessage 方法、getMessage 方法和 sayHelloWorld 消息的簡單 POJO。向 Geronimo 內核注冊此類的實例后,您可以動態地調用該實例,并在運行時,使用依賴性注入將其與其他服務和組件關聯。清單 9 中的代碼說明了簡單的 HelloWorld POJO 類。
清單 9. 簡單的 HelloWorld 服務
| package com.jeffhanson.businesstier.services; import org.apache.log4j.Logger; public class HelloWorld { private static Logger log = Logger.getLogger(HelloWorld.class); private String message = "Hello world"; public void setMessage(String message) { if (message == null || message.length() <= 0) { throw new RuntimeException("HelloWorld.setMessage " + "param is not set"); } this.message = message; } public String getMessage() { return message; } public void sayHello() { log.info(message); } } |
|
結束語
設 計可以對業務更改和事件做出及時響應的敏捷而又有效的 SOA 是一項復雜的任務,但是,圍繞適當設計的 POJO 層構建的 SOA 可以幫助簡化這一任務。Geronimo 平臺提供了框架和工具,您可以使用它通過 POJO 構建靈活的、可擴展的和可維護的 SOA。
來自 “ ITPUB博客 ” ,鏈接:http://blog.itpub.net/374079/viewspace-130287/,如需轉載,請注明出處,否則將追究法律責任。
轉載于:http://blog.itpub.net/374079/viewspace-130287/
總結
以上是生活随笔為你收集整理的[转载]使用 Apache Geronimo 和 POJO 构建 SOA 框架的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Openbravo开发手册
- 下一篇: 人脸识别-特征脸方法