Apache Geronimo 應用服務(wù)器提供了一種巧妙的架構設計,其中的內核對它的任何組件沒(méi)有任何的直接依賴(lài)關(guān)系。內核是服務(wù)的框架,控制著(zhù)服務(wù)生命周期和注冊表。內核不基于 Java? 2 Platform, Enterprise Edition (J2EE)。它使用服務(wù)和組件來(lái)構建特定配置 —— 其中一個(gè)是完全的 J2EE 堆棧。大多數 Geronimo 服務(wù)器是通過(guò) GBeans 被添加并配置成為整個(gè)應用服務(wù)器的一部分的。GBean 是連接組件與內核的接口。每個(gè) GBean 可以維護狀態(tài),依賴(lài)其他 GBean 并與它們相互關(guān)聯(lián),以及操作來(lái)自?xún)群撕推渌?GBean 中的事件。圖 1 展示了帶有 GBean 的 Geronimo 內核的圖形描述。
圖 1. 帶有 GBean 的 Geronimo 內核
可以通過(guò)稱(chēng)為 計劃 的配置文件用控制反轉 (Inversion of Control, IoC) 和依賴(lài)注入將 GBean 插入內核中。這意味著(zhù)可以通過(guò)計劃中的 XML 聲明來(lái)使用 Geronimo 中的 GBean,而且可以通過(guò)屬性和引用來(lái)配置對其他 GBean 的依賴(lài)關(guān)系。清單 1 展示了示例 GBean 配置。
清單 1. 示例 GBean 配置
<gbean name="DefaultThreadPool" class="org.apache.geronimo.pool.ThreadPool">
<attribute name="keepAliveTime">5000</attribute>
<attribute name="poolSize">30</attribute>
<attribute name="poolName">DefaultThreadPool</attribute>
</gbean>>
|
該架構最有趣的部分是,可以通過(guò)編輯計劃文件和更改 GBean 的 XML 聲明,來(lái)向 Geronimo 堆棧添加和刪除完整組件。
大多數 GBean 允許其他開(kāi)放源碼項目和代碼(比如 Jetty、Tomcat 和 OpenEJB)成為 Geronimo 堆棧的一部分,并為這些組件提供 JSR-77 生命周期能力。強大的基于 Java 的組件的一個(gè)示例是 OpenSymphony 的 Quartz 調度器。本文展示了如何創(chuàng )建 Quartz GBean 以將 Quartz 調度器集成到 Geronimo 中。
大多數應用服務(wù)器不具有無(wú)需進(jìn)行大量修改而運行 cron 或 daemon 作業(yè)的能力。雖然一些應用服務(wù)器提供了 API 以創(chuàng )建類(lèi)似 daemon 的應用程序,但它們幾乎全部都缺少豐富而完整的特性集。
由 OpenSymphony 開(kāi)發(fā)的 Quartz 是一個(gè)功能強大的基于 Java 的開(kāi)放源碼調度器。它的特性包括自定義調度、調度持久性(可以與許多類(lèi)型的持久性機制一起使用)、遠程調度能力、容錯、集群,等等。雖然可以獨立運行 Quartz,但它的豐富特性使它成為 J2EE 應用服務(wù)器堆棧包含物的最佳候選項??梢酝ㄟ^(guò)創(chuàng )建啟動(dòng)和停止調度器服務(wù)的 GBean 來(lái)將 Quartz 集成到 Geronimo 中。
開(kāi)發(fā) GBean 是只需要幾個(gè)步驟的簡(jiǎn)單任務(wù)。要開(kāi)發(fā) GBean,需要從不穩定的(或 Milestone 4 (M4))分支中下載 Geronimo 源代碼,并熟悉如何構建 Geronimo(參閱 參考資料 中 Geronimo Wiki 的鏈接以獲得更多信息)。GBean 可以具有屬性、引用和操作。最低限度地,每個(gè) GBean 必須堅持下列指導方針:
- 實(shí)現 org.apache.geronimo.gbean.GBeanLifecycle 接口,如果想要處理生命周期事件的話(huà)。
- 提供構造函數。
- 實(shí)現
doStart()、doStop()和doFail()方法。 - 提供描述構造函數的 GBeanInfo 靜態(tài)初始化器。
- 實(shí)現
public static GBeanInfo getGBeanInfo()方法。 - 創(chuàng )建計劃或編輯現有計劃,以使用 GBean。
記住這些指導方針,每個(gè) GBean 在最低限度上應與 清單 2 所示的構架類(lèi)似。
清單 2. 示例 GBean 構架
/**
* Quartz GBean
*/
public class QuartzGBean implements GBeanLifecycle {
private static final Log log = LogFactory.getLog(QuartzGBean.class);
public QuartzGBean() {
}
public void doFail() {
log.info("Service failed");
//Insert failure code here
}
public void doStart() throws Exception {
log.info("Starting service");
//Insert startup code here
}
public void doStop() throws Exception {
log.info("Stopping service");
//Insert stopping code here
}
public static final GBeanInfo GBEAN_INFO;
static {
GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("QuartzGBean",
QuartzGBean.class);
GBEAN_INFO = infoFactory.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
return GBEAN_INFO;
}
}
|
我使用最低限度 來(lái)強調,是因為所有 GBeans 都必須包含如 清單 2 所示的聲明和實(shí)現。如果使用非默認構造函數,或者如果需要屬性、引用或可調用操作,則 GBEAN_INFO 靜態(tài)初始化器需要分別調用 setConstructor()、addAttribute()、addReference() 和addOperation()。因為本實(shí)例沒(méi)有任何特殊的構造函數、操作、屬性或引用,所以不需要這些調用。
Quartz 是一個(gè)要與 GBean 集成的大項目,因為它僅需要您用 Geronimo 應用服務(wù)器的生命周期來(lái)啟動(dòng)和停止它。這意味著(zhù),當 Geronimo 啟動(dòng)時(shí),您想要 Quartz 啟動(dòng),當 Geronimo 關(guān)閉時(shí),您想要 Quartz 停止。
為了保持本示例的簡(jiǎn)單性,Quartz 配置使用 Quartz 發(fā)行版附帶的默認值。這些默認值位于 quartz.properties 文件中,該文件是 .jar 文件的一部分。要配置 Quartz 以將數據庫用于持久層、遠程調度和其他高級選項,必須創(chuàng )建自定義的 quartz.properties 文件。(參閱 參考資料 以鏈接到 OpenSymphony Web 站點(diǎn),獲得有關(guān)配置這些選項的詳細信息。)
Quartz 調度器易于啟動(dòng)和關(guān)閉;它只通過(guò)調用 StdSchedulerFactory.getDefaultScheduler() 來(lái)檢索調度器對象。要啟動(dòng) Quartz,執行 Scheduler.startup() 方法。要停止 Quartz,執行 Scheduler.shutdown() 方法。要使 Quartz 的生命周期跟隨 Geronimo,將startup() 調用放入 GBean 的 doStart() 方法中,并將 shutdown() 調用放入 GBean 的 doStop() 方法中。清單 3 展示了添加 Quartz 代碼之后完整的 GBean。
清單 3. 新 QuartzGBean
package org.apache.geronimo.quartz;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoBuilder;
import org.apache.geronimo.gbean.GBeanLifecycle;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
/**
* Quartz GBean
*/
public class QuartzGBean implements GBeanLifecycle {
private static final Log log = LogFactory.getLog(QuartzGBean.class);
public QuartzGBean() {
}
public void doFail() {
log.info("Service failed");
try {
doStop();
} catch (Exception e) {
log.error("doStop() failed", e);
}
}
public void doStart() throws Exception {
log.info("Starting service");
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
}
public void doStop() throws Exception {
log.info("Stopping service");
try {
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.shutdown();
} catch (SchedulerException se) {
log.error("Cannot shutdown scheduler.", se);
}
}
public static final GBeanInfo GBEAN_INFO;
static {
GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("QuartzGBean",
QuartzGBean.class);
GBEAN_INFO = infoFactory.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
return GBEAN_INFO;
}
}
|
QuartzGBean 代碼看起來(lái)似乎夠簡(jiǎn)單,但仍需要編譯它并構建合適的 .jar 文件。因為 Geronimo 使用 Apache Maven 作為構建工具,所以本例為 Quartz 使用了 Maven 模塊(參閱 參考資料 以鏈接到 Maven Web 站點(diǎn))。要創(chuàng )建 Maven 模塊,需要 project.xml 文件、project.properties 文件、maven.xml 文件和您的源代碼。本文可供下載的代碼包含完整的 Maven 構建模塊,用于用 Geronimo 編譯 QuartzGBean。要編譯該代碼,請完成下列步驟:
- 將檔案文件下載到 geronimo/modules 目錄,并在此解壓。這將創(chuàng )建一個(gè) quartz 目錄,構建基礎設施位于該目錄下,其中包括 QuartzGBean.java 代碼和單元測試。
- 確保您位于 geronimo/modules/quartz 目錄,并在命令行鍵入
maven。這將編譯、單元測試 GBean,并將其打包到 geronimo-quartz-1.0-snapshot.jar 文件中,該文件存儲于您的 Maven 資源庫中。
既然已經(jīng)創(chuàng )建了 .jar 文件,現在需要對 Geronimo 構建進(jìn)行少量更改以使用您的 GBean。創(chuàng )建 GBean 時(shí),通常創(chuàng )建用于部署 GBean 的計劃。這種情況下,您將編輯一些現有文件以在服務(wù)器啟動(dòng)時(shí)啟動(dòng) GBean,而無(wú)需手動(dòng)啟動(dòng)或部署配置。下列步驟將配置 Geronimo 來(lái)使用新 QuartzGBean。
- 將 Quartz 版本添加到 Geronimo 構建中,以便 Maven 將自動(dòng)下載合適的版本。 通過(guò)添加下列行來(lái)編輯位于 geronimo/etc 目錄的 project.properties 文件:
quartz_version=1.4.5
- 準備程序集模塊以使用 Quartz 和新 .jar 文件。在 geronimo/modules/assembly 目錄中,將 清單 4 中的黑體代碼增加到依賴(lài)關(guān)系部分中的 project.xml 文件中:
清單 4. 程序集 project.xml 依賴(lài)關(guān)系<dependencies> . . . <!--Quartz --> <dependency> <groupId>opensymphony</groupId> <artifactId>quartz</artifactId> <version>${quartz_version}</version> <properties> <repository>true</repository> </properties> </dependency> <dependency> <groupId>geronimo</groupId> <artifactId>geronimo-quartz</artifactId> <version>${pom.currentVersion}</version> <properties> <repository>true</repository> </properties> </dependency> . . . </dependencies><repository>true</repository>代碼導致 Geronimo 構建將 .jar 文件添加到包含最終 Geronimo 程序集的 .jar 資源庫中,所以 Geronimo 構建將附帶指定的 .jar 文件。 - 將 GBean 和依賴(lài)關(guān)系寫(xiě)入計劃中。要確保 QuartzGBean 在 Geronimo 啟動(dòng)時(shí)啟動(dòng),雖然可以創(chuàng )建自己的計劃,但編輯現有計劃更容易。為此,編輯位于 geronimo/modules/assembly/src/plan 目錄中的 j2ee-server-plan.xml 文件。將依賴(lài)關(guān)系添加到計劃中最后一個(gè)
</dependency>標記之后和第一個(gè)<gbean>標記之前,如 清單 5 所示。
清單 5. j2ee-server-plan.xml 依賴(lài)關(guān)系添加<!-- Quartz --> <dependency> <uri>opensymphony/jars/quartz-${quartz_version}.jar</uri> </dependency> <dependency> <uri>geronimo/jars/geronimo-quartz-${geronimo_version}.jar</uri> </dependency> - 將 GBean 添加到同一文件。在文件底部的最后一個(gè)
</configuration>標記之前,添加下列行:<gbean name="QuartzService" class="org.apache.geronimo.quartz.QuartzGBean"/>
現在只需要重新構建程序集模塊。這使得新配置和已更新計劃部分成為 Geronimo 服務(wù)器的一部分。要重新構建程序集模塊,請將目錄更改為 geronimo/modules/assembly,并在命令提示行鍵入 maven。當程序集模塊構建完成時(shí),在 geronimo/modules/assembly/target 目錄中就會(huì )有 geronimo-assembly-1.0-SNAPSHOT.jar 文件了。要運行 Geronimo,請從命令行執行 java -jar bin/server.jar-v。-v 通常不是運行 Geronimo 所必需的,但在此包括它是為了將日志輸出發(fā)送到終端窗口,以便您可以看到發(fā)生了什么。
用 -v 啟動(dòng) Geronimo 時(shí),記下日志,并觀(guān)察新 GBean 啟動(dòng) Quartz,如 清單 6 所示。
清單 6. 帶有 QuartzGBean 的 Geronimo 啟動(dòng)日志
14:53:13,462 INFO [QuartzGBean] Starting service
14:53:13,615 INFO [SimpleThreadPool] Job execution threads will use class loader of
thread: main
14:53:13,697 INFO [RAMJobStore] RAMJobStore initialized.
14:53:13,699 INFO [StdSchedulerFactory] Quartz scheduler 'DefaultQuartzScheduler'
initialized from default resource file in
Quartz package: 'quartz.properties'
14:53:13,699 INFO [StdSchedulerFactory] Quartz scheduler version: 1.4.5
14:53:13,701 INFO [QuartzScheduler] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED
started.
|
關(guān)閉 Geronimo 時(shí),記下日志中的差別。
清單 7. 帶有 QuartzGBean 的 Geronimo 關(guān)閉日志
14:53:41,426 INFO [QuartzGBean] Stopping service
14:53:41,450 INFO [QuartzScheduler] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED
shutting down.
14:53:41,452 INFO [QuartzScheduler] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED
paused.
14:53:41,459 INFO [QuartzScheduler] Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED
shutdown complete.
|
對于大多數開(kāi)放源碼項目,實(shí)現少量函數并編輯少量配置文件是編寫(xiě) GBeans 所需的全部工作。但是,一些集成計劃(比如 Jetty、Tomcat 或 OpenEJB)可能需要在編碼中進(jìn)行更多顯著(zhù)的修改。這些集成在代碼中需要多個(gè) GBean、配置和鉤子。然而,類(lèi)似 Quartz 的應用程序是簡(jiǎn)單集成的優(yōu)秀候選項,因為它只需要啟動(dòng)和關(guān)閉。有很多與 Quartz 一樣簡(jiǎn)單的有助于集成的開(kāi)放源碼項目。
- 我想感謝 Apache Geronimo 團隊的 Bruce Snyder 和 Dain Sundstrom,他們幫我審閱了本文。
- 本文同時(shí)在 IBM developerWorks 和 Virtuas Solutions 上發(fā)表。
| 描述 | 名字 | 大小 | 下載方法 |
|---|---|---|---|
| Quartz GBean Maven code module | quartzgbean.zip | 10 KB | HTTP |
學(xué)習
- 您可以參閱本文在 developerWorks 全球站點(diǎn)上的 英文原文。
- 參閱 Apache Geronimo Wiki 獲得有關(guān)的最新信息,以及有關(guān)下載 M4 版本的詳細信息。
- 訪(fǎng)問(wèn) Quartz OpenSymphony 站點(diǎn)以獲得有關(guān)該作業(yè)調度系統的詳細信息。
- 訪(fǎng)問(wèn)官方 Apache Geronimo Web 站點(diǎn) 以查閱 Apache Geronimo 的新特性。
- 使用 Sing Li 的“Geronimo!第 1 部分: 支持 J2EE 1.4 引擎”(developerWorks,2005 年 5 月)作為向導來(lái)熟悉 Geronimo,然后在“Geronimo!第 2 部分: 馴服 J2EE 1.4 這匹野馬”(developerWorks,2005 年 5 月)中實(shí)踐。
- 訪(fǎng)問(wèn) developerWorks Apache Geronimo 項目區以訪(fǎng)問(wèn) Geronimo 開(kāi)發(fā)者的資源。
- 訪(fǎng)問(wèn) developerWorks 開(kāi)放源碼專(zhuān)區 ,獲得廣泛的技術(shù)信息、工具和更新,以幫助您使用開(kāi)放源碼技術(shù)進(jìn)行開(kāi)發(fā),并與 IBM 產(chǎn)品結合使用。
- 瀏覽 developerWorks 開(kāi)放源碼專(zhuān)區中所有的 Apache 文章 和免費的 Apache 教程。
獲得產(chǎn)品和技術(shù)
- 訪(fǎng)問(wèn) Apache Maven Web 站點(diǎn) 以下載信息和文檔。Maven 是項目管理和理解工具,用于自動(dòng)化 Geronimo 應用程序的部署。
- 下載 Gluecode Standard Edition,這是一款基于 Apache Geronimo 的開(kāi)放源碼應用服務(wù)器。
- 利用 IBM 試用軟件 改革您的下一個(gè)開(kāi)放源碼開(kāi)發(fā)項目,該軟件可以下載,也可以從 DVD 安裝。
討論
- 參與論壇討論。
- 加入 Apache Geronimo 團隊 以討論 #geronimo IRC 通道(IRC 客戶(hù)機所需的)。
Jeff Genender 是 Virtuas Solutions 的實(shí)踐主管,致力于用 Java 架構領(lǐng)導公司和實(shí)現開(kāi)放源碼解決方案。他是 Apache Geronimo 的提交者和 PMC 成員。他是 Enterprise Java Servlets(2001 年 9 月,Addison Wesley Longman)的作者,目前正在撰寫(xiě) JBoss Live (SourceBeat Publishing)。

