Spring Web Flow 2.0 M4 - 請求反饋
在GWT客戶端程式碼中啟用測試驅動開發
在過去的幾個月裡,我一直在與不同的客戶合作使用Google Web Toolkit [GWT] 的專案。我喜歡GWT主要是因為它的Java到javascript編譯器。這是讓普通Java開發人員無需學習新語言即可建立RIA的關鍵。
我一直都是測試驅動開發的粉絲,令我失望的是,乍一看,TDD和GWT似乎無法協同工作。
測試GWT程式碼有點問題。問題的核心是GWT程式碼在執行之前被編譯成javascript。在許多情況下,GWT.create()語句……
建立 OSGi 捆綁包
在接觸 OSGi 時,首先要掌握的概念之一就是“捆綁包”(bundle)。在這篇文章中,我想更詳細地探討一下捆綁包究竟是什麼,以及一個普通的 jar 檔案如何能被轉換成一個 OSGi 捆綁包。那麼,廢話不多說,
什麼是捆綁包?
OSGi 規範將捆綁包描述為“模組化的單元”,它“由 Java 類和其他資源組成,這些資源可以一起為終端使用者提供功能”。到目前為止都還好,但捆綁包究竟*是什麼*?再次引用規範:
捆綁包是一個 JAR 檔案,它
- 包含 [...] 資源
- 包含一個清單檔案,描述 JAR 檔案的內容並提供有關捆綁包的資訊
- 可以在 JAR 檔案內的 OSGI-OPT 目錄或其子目錄中包含可選文件
總之,捆綁包 = jar + OSGI 資訊(在 JAR 清單檔案 - META-INF/MANIFEST.MF 中指定),不需要額外的檔案或預定義的資料夾佈局。這意味著要從一個 jar 建立一個捆綁包,只需在 JAR 清單中新增一些條目即可。
OSGi 元資料
OSGi 元資料由清單條目表示,這些條目告訴 OSGi 框架捆綁包提供或/和需要什麼。規範中列出了大約 20 個清單頭,但我們將只關注你最有可能使用的那些。
Export-Package
顧名思義,此頭指定了捆綁包中要匯出的包,以便其他捆綁包可以匯入。*只有*此頭指定的包會被匯出,其餘的將是私有的,不會在包含捆綁包外部可見。
Import-Package
與 Export-Package 類似,此頭指定了由捆綁包匯入的包。同樣,*只有*此頭指定的包才會被匯入。預設情況下,匯入的包是強制性的——如果匯入的包不可用,匯入捆綁包將無法啟動。
Bundle-SymbolicName
這是唯一必需的頭,此條目指定了一個捆綁包的唯一識別符號,基於反向域名約定(也用於 Java 包)。Bundle-Name
為此捆綁包定義一個不帶空格的可讀名稱。建議設定此頭,因為它比 Bundle-SymbolicName 能提供更短、更有意義的捆綁包內容資訊。Bundle-Activator
BundleActivator 是一個 OSGi 特定的介面,允許 Java 程式碼在捆綁包被 OSGi 框架啟動或停止時收到通知。此頭的值應包含啟用器類的完全限定名,該類應為公共的幷包含一個沒有引數的公共建構函式。Bundle-Classpath
當 jar 包含嵌入式庫或不同資料夾下的類包時,此頭非常有用,它可以擴充套件預設的捆綁包類路徑(預設情況下,類期望直接在 jar 根目錄下可用)。Bundle-ManifestVersion
這個鮮為人知的頭指定了用於讀取此捆綁包的 OSGi 規範版本。1 表示 OSGi release 3,而 2 表示 OSGi release 4 及更高版本。由於 1 是預設版本,強烈建議指定此頭,因為 OSGi release 4 捆綁包在 OSGi release 3 下可能無法按預期工作。下面是一個示例,取自 Spring 2.5.x 核心捆綁包清單,使用了上面提到的一些頭。
Bundle-Name: spring-core
Bundle-SymbolicName: org.springframework.bundle.spring.core
Bundle-ManifestVersion: 2
Export-Package:org.springframework.core.task;uses:="org.springframework.core,org.springframework.util";version=2.5.1 org.springframework.core.type;uses:=org.springframework.core.annotation;version=2.5.1[...]
Import-Package:org.apache.commons.logging,edu.emory.mathcs.backport.java.util.concurrent;resolution:=optional[...]
在 OSGi 元資料上花費的大部分時間可能都在 Export/Import 包條目上,因為它們描述了捆綁包(即你的模組)之間的關係。對於包來說,沒有任何東西是隱式的——只有提到的包才會被匯入/匯出,其他的則不會。這同樣適用於子包:匯出 org.mypackage 只會匯出*此*包,而不會匯出其他任何東西(如 org.mypackage.util)。匯入也是如此——即使一個包在 OSGi 空間中可用,除非被某個捆綁包明確匯入,否則該捆綁包也看不到它。
總而言之,如果捆綁包 A 匯出了 org.mypackage 包,而捆綁包 B 想使用它,那麼捆綁包 A 的 META-INF/MANIFEST.MF 應該在其 Export-Package 頭中指定該包,而捆綁包 B 應該在其 Import-Package 條目中包含它。
包的考慮
雖然匯出相當直接,但匯入稍微複雜一些。應用程式通常會透過搜尋環境中可用的庫來優雅地降級,並僅使用可用的庫,或者庫會包含使用者未使用的程式碼。例如,日誌(使用 JDK 1.4 或 Log4j)、正則表示式(Jakarta ORO 或 JDK 1.4+)或併發實用程式(JDK 5 中的 java.util 或 JDK 1.4 的 backport-util-concurrent 庫)。
在 OSGi 術語中,根據包的可用性來依賴包相當於一個*可選*的 Package-Import。你在前面的示例中已經見過這樣的包
```code Import-Package: [...]edu.emory.mathcs.backport.java.util.concurrent;resolution:=optional ```由於在 OSGi 中,同一類的多個版本可以存在,因此最好在匯出和匯入包時都指定類包的版本。這是透過新增到每個包聲明後的 version 屬性來完成的。OSGi 支援的版本格式為 <major>.<minor>.<micro>.<qualifier>,其中 major、minor 和 micro 是數字,而 qualifier 是字母數字。
版本*的含義*完全由捆綁包提供者決定,但是,建議使用流行的編號方案,例如 Apache APR 專案的方案,其中
- <major> - 表示不保證相容性的重大更新
- <minor> - 表示保留與舊 minor 版本相容的更新
- <micro> - 從使用者角度來看,表示微不足道的更新,與舊版本完全相容
- <qualifier> - 是使用者定義的字串 - 它不常用,可以為版本號提供一個額外的標籤,例如構建號或目標平臺,但沒有標準化含義。
預設版本(如果屬性缺失)是 "0.0.0"。
雖然匯出的包必須指定一個特定版本,但匯入者可以使用數學區間表示法來指定一個範圍——例如
[1.0.4, 2.0) 將匹配版本 1.0.42 及以上直到 2.0(不包括)。請注意,僅指定一個版本而不是一個區間將匹配所有大於或等於指定版本的包,即
Import-Package: com.mypackage;version="1.2.3"
等同於
Import-Package: com.mypackage;version="[1.2.3, ∞)"
最後一個提示是,無論版本是範圍還是單個版本,請*務必*在指定版本時使用引號。
使用 OSGi 元資料
現在我們已經瞭解了捆綁包是什麼,讓我們看看我們可以使用哪些工具來將現有的 jar 檔案 osgi 化。
手動
這種 DIY 方法並不推薦,因為很容易出現拼寫錯誤和多餘的空格,這可能會導致清單無效。即使使用智慧編輯器,清單格式本身也可能導致一些問題,因為它每行限制為 72 個空格,如果超過此限制,可能會導致難以理解的問題。手動建立或更新 jar 不是一個好主意,因為 jar 格式要求 META-INF/MANIFEST.MF 條目是歸檔檔案中的第一個條目——如果不是,即使它存在於 jar 中,清單檔案也不會被讀取。手動方法確實推薦用於沒有其他選擇的情況。
但是,如果有人確實想/需要直接處理清單,那麼應該使用一個可以處理 UNIX/DOS 空格的編輯器,並配合一個合適的 jar 建立實用程式(例如 JDK 自帶的 jar 工具)來處理所有 MANIFEST 要求。
Bnd
Bnd 代表 BuNDle tool,是 Peter Kriens(OSGi 技術官)建立的一個好用的工具,它“幫助 [...] 建立和診斷 OSGi R4 捆綁包”。Bnd 解析 Java 類以瞭解可用的和匯入的包,從而可以建立相應的 OSGi 條目。Bnd 提供一系列指令和選項,可以自定義生成的工件。bnd.jar 本身的好處在於它可以從 命令列執行,透過 Ant 的專用 任務執行,或者作為 外掛整合到 Eclipse 中。
Bnd 可以從類路徑或 Eclipse 專案中的類建立 jar,或者透過新增所需的 OSGi 工件來 osgi 化現有的 jar。此外,它可以列印和驗證給定 jar 的 OSGi 資訊,使其成為一個強大而易於使用的工具。
首次使用的使用者可以使用 Bnd 來檢視將新增到普通 jar 中的 OSGi 清單。讓我們選擇一個普通 jar,例如 c3p0(一個優秀的連線池庫),然後發出一個列印命令。
```code java -jar bnd.jar print c3p0-0.9.1.2.jar ```
輸出相當大,包含幾個部分。
- 通用清單資訊
[MANIFEST c3p0-0.9.1.2.jar] Ant…
Spring Batch 最近更改和即將釋出的 m4 版本
我們一直在努力開發 Spring Batch,為 Spring Portfolio 2.5 版本系列做準備,我認為現在是時候向大家更新一下情況了。在這篇文章中,我將稍微擴充套件一下領域模型,以及我們提高一些核心領域物件知名度、增加其職責的決定。我還會提供一些即將到來的、直至 1.0 的版本的一些預覽,以便大家有機會發表評論。
作為一種道歉:內部發生了一些相當重大的變化……
一些決定很簡單——就像 SpringSource 收購 Covalent 一樣
我 上一篇部落格 展示了 Spring 如何超越 EJB。 BZ Media 等的研究表明,Apache Tomcat 是領先的開源應用程式伺服器,市場佔有率為 64%。Spring 和 Tomcat 的主導地位眾所周知。人們可能不知道的是,成千上萬的組織將 Spring 執行在 Tomcat 上作為其中介軟體基礎設施。這些組織希望有一個公司來提供他們成功所需的各種產品和服務。
今天我們宣佈收購 Covalent Technologies。Covalent 不僅帶來了 Apache 的領導地位,而且我們合併後的公司現在還在 Apache Tomcat 和 HTTP 領域擁有重要的領導地位。兩週前,Sun 斥資 10 億美元收購了 LAMP 中的“M”。現在 Covalent outstanding 的 Apache 專業知識和服務成為 SpringSource 的一部分,我們在“A”(Apache)領域處於領先地位。我們一直致力於技術領先,因此對我們與 Covalent 共同取得的成就感到非常興奮。在過去的幾年裡,Covalent 以其對 Tomcat 和 Apache HTTP 等 Apache 專案的支援,在市場上贏得了極高的聲譽。其數百名支援客戶包括超過一半的財富 500 強公司,以及輝瑞(Pfizer)、強生(Johnson & Johnson)、英國電信(BT)、NASA、英特爾(Intel)、蘇格蘭皇家銀行(Royal Bank of Scotland)和貝爾斯登(Bear Stearns)等知名企業。我們的公告……
Spring 2.5 的全面註解支援
Spring 2.5 的核心主題之一是全面的基於註解的配置。我們已經討論和撰寫了很多關於 **@Autowired**、Spring MVC 的 **@RequestMapping** 以及對使用 JUnit4 或 TestNG 編寫的註解測試的新支援。**@Autowired** 毫無疑問是 Spring 2.5 註解的核心,可用於服務元件、Web 元件、單元測試——甚至在使用 Spring 的 **@Configurable** 和 AspectJ weaving 時也可以用於領域物件。Spring MVC 的 **@RequestMapping** 也同樣靈活,支援多種 handler 方法簽名變體。
今天我……
Spring Dynamic Modules 達到 1.0 版本!
好吧,這比我們最初預期的要花費更長的時間,但我很高興地說,Spring Dynamic Modules 專案今天達到了其 1.0 版本里程碑。當我於 2006 年 9 月首次釋出有關此主題的文章(“Spring OSGi 支援勢頭強勁”)時,最初的規範只是 Spring Framework 的一個問題附件,並且與更廣泛的 OSGi 社群的聯絡才剛剛開始形成。
快進十八個月,Spring Dynamic Modules 已成為 Spring Portfolio 中的一個成熟專案,擁有來自 SpringSource、BEA 和 Oracle 的提交者。BEA 和 Oracle 都使用 Spring Dynamic Modules 來構建自己的基於 OSGi 的產品(例如,請參閱“WebLogic Event Server - 我們為什麼使用 Spring”),並且 Spring Dynamic Modules 討論組擁有近 1000 名成員。OSGi 聯盟本身已經成立了一個 企業專家組……
Spring Dynamic Modules 1.0 已釋出
我很高興(與 Adrian 一起)報告,在經歷了 3 個里程碑和 2 個釋出候選版本之後,Spring Dynamic Modules(前身為 Spring OSGi)1.0 已釋出。
自上次 帖子(關於 1.0 M1)以來,許多功能得到了改進或新增(大約 1.0 M1);我將在未來的文章中詳細介紹它們(還有詳細介紹該庫的參考 文件),所以這裡我只列舉幾項:
- 一致性
我們希望提供一個強大、簡單且一致的程式設計模型。這就是為什麼 Spring Dynamic Modules 構建在 Spring 之上,並使用其經過驗證的概念、可靠性和普遍性。
- 高度非侵入性
使用 Spring DM 的推薦方法是*不要*在程式碼中使用其類,或者在捆綁包清單中匯入它們。如果您不在程式碼中使用 Spring,而僅用於應用程式配置,則相同的規則適用。Spring DM 會為您建立應用程式上下文,因此您無需依賴 Spring 或 Spring DM。而且不用擔心自定義名稱空間或 XML 模式等問題——我們已經解決了它們。
- OSGi 服務動態生命週期管理
這是 Spring DM 最重要的功能之一——能夠像處理*普通* Bean 一樣與 OSGi 服務進行互動。您可以在不編寫任何程式碼的情況下發布和消耗 OSGi 服務;我們會為您處理動態性——並且您擁有完全的控制權(未來將提供更多關於此的資訊)。
- 更智慧的整合測試框架
由於我們在內部廣泛使用了 Spring-DM 整合測試,因此我們改進了預設設定、Maven 整合,並使自動清單生成比以前更快、更智慧。例如,該框架會自動確定測試捆綁包中可用的類,並且不會為其生成匯入。
- 簡單的捆綁包互動
Andy Piper(部落格)添加了一種簡單、宣告式的方法,可以根據模組生命週期和 Spring Bean 依賴關係來安裝/啟動/停止/更新捆綁包。
- 受管啟動/關閉上下文建立
在 OSGi 中,應用程式被分解成各種相互依賴服務的模組(也稱為捆綁包)。這會在模組之間建立依賴關係樹,這在啟動和關閉過程中很重要。傳統上,這可以透過根據依賴順序安裝和啟動捆綁包來解決,但這並不能完全解決問題。如 OSGi 規範所建議的,耗時初始化的 OSGi 服務(如連線池)應該依賴於與啟動和停止捆綁包所用的執行緒不同的執行緒。這意味著,如果一個捆綁包已啟動,並不意味著它的服務已經可用。並非所有應用程式都已準備好在啟動時等待其所需的服務——實際上,很少有應用程式這樣做。這意味著捆綁包將失敗,因為它依賴於在幾毫秒後釋出的*其他*服務(OSGi 預設情況下是一個 VM 內平臺,事物*非常*快速地發生)。
這種行為並不少見——實際上,在多核平臺上,多個捆綁包在啟動時很常見。Spring DM 透過確定依賴關係(來自 Spring 配置)並在建立應用程式上下文之前等待它們可用,來解決此問題。在關閉時將進行類似的流程,Spring DM 將根據依賴順序停止上下文,因此您不必擔心啟動或停止您的捆綁包。
- 無執行緒依賴等待
在討論依賴機制時,我不能不提 Hal Hildebrand(請參閱他的 部落格)實現的“無執行緒”依賴等待方法(我知道這聽起來有點像矛盾修飾法——我們正在為其尋找一個好名字)。由於模組正常啟動需要各種服務可用,因此需要某種形式的等待/監控,這通常需要使用執行緒。
然而,在一個 OSGi 平臺上,可以有(並且將會有)多個模組(很容易達到幾十個)——每個模組使用一個等待執行緒根本無法擴充套件。我們努力改進了這個模型,並且我認為我們提供了一個非常好的解決方案——為等待過程根本*不*使用執行緒。這意味著,無論部署了 3 個捆綁包還是 300 個,只要您的模組沒有實際啟動,就不會花費任何 CPU 時間。
Spring Dynamic Modules 不僅僅是“spring-ify”一個 API,而是處理一個不同的執行時環境。
在工具方面,Spring IDE 支援 Spring DM 名稱空間,並且(感謝 Christian)還為 Eclipse PDE 提供了 Spring-DM 特定的 目標,這些功能在 Spring IDE 的 nightly builds 中可用(有關安裝和使用外掛的更多資訊,請參閱參考文件 可用)。
未來方向
既然 1.0 已釋出,下一步是什麼?有很多領域需要涵蓋。
Web 支援
OSGi 平臺提供了一個專用的 Http Service,但使用它需要編寫程式碼。諸如資源載入、JSP 生成和部署之類的事情可以大大簡化。這是 1.1 版本的主要關注點。
持久化
現代持久化工具提供高階功能,如懶載入,這些功能會違反 OSGi 環境強制的模組化邊界,因為它們依賴於類生成和代理。我們希望解決這個問題,就像 Web 支援一樣,無論使用純 JDBC 或/和 ORM 工具,都能提供順暢的體驗。
AOP
在持久化問題之後,我們正在尋求在 OSGi 中執行通用 AOP 的解決方案。這是一個棘手的難題,要正確處理需要內部 OSGi 平臺支援。好訊息是,像 Equinox Aspects 這樣的專案已經開闢了道路,而 OSGi 企業專家組(EEG)也已將該問題提上日程。
廢話少說
如果您想了解更多關於 Spring Dynamic Modules 的資訊,請檢視 專案頁面和參考文件,並使用我們的郵件列表(論壇很快就會出現)。此外,最近我們還製作了一些 OSGi/Spring DM 螢幕截圖,可在 Spring DM 主頁上找到。第一個(由兩部分組成),由我自己製作,演示瞭如何快速建立一個專案來進行 Spring DM 的整合測試。
為什麼要做整合測試?因為使用 Spring DM 進行整合測試非常簡單快捷,並且是學習 OSGi(尤其是模組化方面)的非常有效的方式。
未來還會有更多螢幕截圖——請告訴我們您想看什麼,我們將根據請求數量對其進行排隊。
廢話不多說,“使用 Spring DM 進行 OSGi 整合測試”
領域物件依賴注入功能的新改進
Spring 的依賴注入 (DI) 機制允許配置應用程式上下文中定義的 bean。如果您想將相同的思想擴充套件到非 bean 呢?Spring 對領域物件 DI 的支援利用 AspectJ 織入將 DI 擴充套件到任何物件,即使它是由 Web 或 ORM 框架建立的。這使得建立具有豐富領域行為的物件成為可能,因為領域物件現在可以與注入的物件協作。在本部落格中,我將討論 Spring 框架在此領域的最新改進。
領域物件 DI 背後的核心思想非常簡單:一個 AspectJ 織入切面選擇與任何符合特定規範的物件的建立或反序列化對應的連線點。對這些連線點的通知將依賴項注入到正在建立或反序列化的物件中。當然,魔鬼在細節中。例如,如何選擇與反序列化對應的連線點,或者如何每個物件只注入一次依賴項?透過提供一些預先編寫的...

