級別: 高級
Tom Alcott
(alcott@us.ibm.com), IT 咨詢專家, IBM Software Group, Worldwide Sales
Roland Barcia (barcia@us.ibm.com), 認證 IT 專家, IBM
Jim Knutson (knutson@us.ibm.com), WebSphere J2EE 架構(gòu)師, IBM
2006 年 12 月 18 日
如果您考慮將 Spring 或 Hibernate 與 IBM? WebSphere? Application Server 結(jié)合使用,則此必讀文章向您闡述了需如何配置這些框架,以適用于 WebSphere Application Server 的各種場景。本文還描述了不支持的場景以及應(yīng)該避免的場景。本文不是對某一框架的認可或推薦,而是為決定實現(xiàn)此類場景的人員提供的重要參考。
摘自 IBM WebSphere 開發(fā)者技術(shù)期刊。
Spring 和 Hibernate 是兩個開放源代碼項目,有些客戶可能有興趣使用它們。本文描述如何配置這些框架,以便與 WebSphere Application Server 一起在各種場景中使用。不過,本文不是對某一框架的認可或推薦。IBM 也不直接支持其中任何一個開放源代碼項目。IBM 支持有限制地使用這些應(yīng)用程序框架(如下面所述),就像它支持在 WebSphere Application Server 上運行的任何客戶的應(yīng)用程序一樣。本文還描述一些不支持的場景,在 WebSphere Application Server 和堆棧產(chǎn)品中應(yīng)該避免此場景。
一個用戶理應(yīng)關(guān)注的問題是那些使用開放源代碼的項目所獲得的支持,以及使用開放源代碼對供應(yīng)商支持其許可產(chǎn)品的影響。IBM 了解某些客戶可能希望將非 IBM 的框架和 IBM WebSphere Application Server 結(jié)合使用,并且在為客戶提供一些信息,以促進他們?yōu)?IBM WebSphere Application Server 創(chuàng)建最可靠的操作環(huán)境。IBM 考慮了客戶安裝的開放源代碼和應(yīng)用程序框架,它們或者綁定為應(yīng)用程序的一部分,或者作為共享庫成為應(yīng)用程序代碼的一部分。在使用開放源代碼項目時通過謹慎地利用此信息,客戶可以滿懷信心地使用 IBM 產(chǎn)品,并繼續(xù)訪問 IBM 產(chǎn)品和技術(shù)支持。如果在將這些框架與 WebSphere 產(chǎn)品結(jié)合使用時遇到問題,IBM 將盡力確保 WebSphere 產(chǎn)品不出現(xiàn)問題。
如果客戶認真研究了本文中的建議,并記住避免和理解以下幾個關(guān)鍵點,則預(yù)期可以安全地在 IBM 產(chǎn)品上使用 Spring 和 Hibernate 之類的框架:
-
客戶必須確保按 WebSphere Application Server 允許的方式使用這些框架。具體說來,這意味著客戶在使用內(nèi)部產(chǎn)品接口時,不應(yīng)使用框架——遺憾的是,許多開放源代碼框架在未經(jīng)認真配置的情況下就這樣使用了。客戶應(yīng)避免在 WebSphere 上明確記錄應(yīng)避免的場景。
-
對于開放源代碼框架,客戶應(yīng)該確保理解并能夠訪問他們與 WebSphere Application Server 一起使用的框架的匹配源代碼和二進制。
-
建議客戶從開放源代碼社區(qū)或使用開放源代碼社區(qū)的合作伙伴那里獲取框架的補救性服務(wù)。
有關(guān) IBM 支持和策略的詳細信息,請參考 IBM Support Handbook 和 WebSphere Application Server Support Statement。
盡管在開放源代碼環(huán)境中使用 WebSphere Application Servers 時按照本文的建議做法有助于增強您的體驗,但本文并沒有列出開放源代碼組件影響 WebSphere Application Server 操作或其他組件操作的所有情況。使用開放源代碼的用戶務(wù)必檢查所有組件的規(guī)范,以避免出現(xiàn)許可、支持和技術(shù)問題。
在本文的剩余部分中,當(dāng)使用術(shù)語“支持”或“受支持”時,描述的用法僅限于使用 IBM 有文檔記錄的功能。作者已盡了最大努力來提供有關(guān)如何配置和使用這些框架的建議,以確保其用法與記錄的產(chǎn)品行為一致。
![]() ![]() |
Hibernate 是傳統(tǒng)的 Java? 對象 (POJO) 的開放源代碼持久性框架,它通過 XML 配置文件提供 POJO 到關(guān)系數(shù)據(jù)庫表的與對象相關(guān)的映射。Hibernate 框架是應(yīng)用程序調(diào)用的、用于數(shù)據(jù)持久性的數(shù)據(jù)訪問抽象層。此外,Hibernate 還提供了從 Java 類到數(shù)據(jù)庫表(以及從 Java 數(shù)據(jù)類型到 SQL 數(shù)據(jù)類型)的映射以及數(shù)據(jù)查詢和檢索功能。Hibernate 生成必需的 SQL 調(diào)用,還負責(zé)結(jié)果集處理和對象轉(zhuǎn)換。
Hibernate 由 Gavin King(Hibernate 項目的奠基人)領(lǐng)導(dǎo)的軟件開發(fā)團隊開發(fā),目的是解決 EJB 2.x 實體 EJB 中存在的諸多缺陷。Hibernate 與 JBoss Group 緊密關(guān)聯(lián),這是由于 JBoss 雇傭了大量的一流 Hibernate 開發(fā)人員的結(jié)果。最近,在 Java Community Process (JCP) 中的持久性框架的發(fā)展中已涉及 Hibernate,并且 Hibernate 的許多概念已合并到 Java Persistence API (JPA) 規(guī)范中。最新版本的 Hibernate 將發(fā)展為符合 JPA 規(guī)范。JPA 似乎將成為主要的 Java 持久性 API。具體說來,JPA 是 Java EE 5 必要部分。(有關(guān)如何使用 Hibernate 的 developerWorks 文章,請參見參考資料。)
盡管下文的描述中支持在 WebSphere Application Server 上使用 Hibernate,但是 IBM 并不直接支持 Hibernate。任何人使用 Hibernate 時都需要按 Hibernate Project Support page 的描述獲取對它的支持。客戶應(yīng)該保留與開源項目相關(guān)的源數(shù)據(jù),以用于問題調(diào)試。
以下場景描述了有關(guān)如何將 Hibernate 與 WebSphere Application Server 和 WebSphere 堆棧產(chǎn)品結(jié)合使用的一些可能場景。這些僅是示例場景,不應(yīng)認為是推薦的場景。前文已提到,客戶應(yīng)該保留與開源項目相關(guān)的源數(shù)據(jù),以用于問題調(diào)試
使用 WebSphere Application Server 數(shù)據(jù)源
為使 Hibernate 從 WebSphere Application Server 獲取數(shù)據(jù)庫連接,必須使用 Java EE(以前稱為 J2EE)規(guī)范中強制規(guī)定的資源引用。這可以確保 WebSphere Application Server 能夠為連接池、事務(wù)語義和隔離級別提供正確的行為。通過設(shè)置 hibernate.connection.datasource 屬性(在 Hibernate 配置文件中進行了定義)將 Hibernate 配置為從 WebSphere Application Server 檢索數(shù)據(jù)源,以引用在模塊的部署描述符中定義的資源引用(例如 java:comp/env/jdbc/myDSRef
)。例如:
<property name="hibernate.connection.datasource"> java:/comp/env/jdbc/myDSRef </property> |
Web 應(yīng)用程序的 Java EE 資源引用在 WAR 文件級別定義,這意味著容器中的所有 Servlet 和 Java 類均共享資源引用。在 EJB 模塊內(nèi)部,資源引用在各個 EJB 組件上定義。這意味著,如果許多 EJB 組件都使用相同的 Hibernate 配置,則每個 EJB 必須在每個 EJB 組件上定義相同的引用名稱。這會導(dǎo)致復(fù)雜的情況,稍后我們將進一步討論。
配置了數(shù)據(jù)源之后,確保 Hibernate 正常工作的下一個步驟是正確配置事務(wù)支持。
為了正確地使用事務(wù),Hibernate 需要兩個重要部分的配置。第一個部分是 hibernate.transaction.factory_class,它定義事務(wù)控制,第二個部分是 hibernate.transaction.manager_lookup_class,它定義注冊事務(wù)同步的機制,這樣,當(dāng)持久性管理器需要與數(shù)據(jù)庫同步更改時會在事務(wù)端得到通知。對于事務(wù)控制,同時支持容器管理的配置和 Bean 管理的配置。將 Hibernate 和 WebSphere Application Server 結(jié)合使用時,必須在 Hibernate.cfg.xml 中設(shè)置以下屬性:
-
對于容器管理的事務(wù):
<property name="hibernate.transaction.factory_class"> org.hibernate.transaction.CMTTransactionFactory </property> <property name="hibernate.transaction.manager_lookup_class"> org.hibernate.transaction.WebSphereExtendedJTATransactionLookup </property>
-
對于 Bean 管理的事務(wù):
<property name="hibernate.transaction.factory_class"> org.hibernate.transaction.JTATransactionFactory </property> <property name="hibernate.transaction.manager_lookup_class"> org.hibernate.transaction.WebSphereExtendedJTATransactionLookup </property> <property name="jta.UserTransaction"> java:comp/UserTransaction </property >
jta.UserTransaction 屬性將工廠類配置為從 WebSphere 容器獲取 UserTransaction 對象實例的實例。
WebSphere Application Server V6.x 和更高版本在 WebSphere 平臺上支持 hibernate.transaction.manager_lookup_class 屬性,WebSphere Business Integration Server Foundation V5.1 和更高版本也支持此屬性。此屬性將 Hibernate 配置為使用在 WebSphere Business Integration Server Foundation V5.1 和 WebSphere Application Server V6.0 中引入的 ExtendedJTATransaction 接口,WebSphere ExtendedJTATransaction 接口建立了一個模式,并通過 JTA 1.1 規(guī)范在 Java EE 5 中正式確立。
WebSphere Application Server 環(huán)境中 Hibernate 的使用模式
當(dāng)結(jié)合使用 Hibernate 和 WebSphere Application Server 時,Hibernate 的“按請求會話”和“長對話”模式均可使用。客戶必須選擇適用于其應(yīng)用程序的模式,不過我們主張使用“按請求會話”模式,因為它可以提供更好的擴展性。
-
多個隔離級別
可共享的連接通過讓多個資源用戶能夠共享現(xiàn)有的連接,改進了在 WebSphere Application Server 中的性能。不過,如果可共享的連接和多個隔離級別都是必需的,則為每個連接配置定義單獨的資源引用和 Hibernate 會話工廠。不能夠更改共享連接的隔離級別。因此,也不可能使用 hibernate.connection.isolation 屬性在共享連接上設(shè)置隔離級別。有關(guān)連接共享的策略和約束的詳細信息,請參見 在 WebSphere Application Server V5 中共享連接。(盡管本文通常適合于在 WebSphere Application Server V5 上使用的所有共享連接,但是連接共享建議仍適用于在 V6.x 上運行的 Hibernate。)
-
Web 應(yīng)用程序
可以在 HttpSession 對象中使用和存儲 Hibernate 的“長對話”會話;不過,Hibernate 會話持有活動實例,由于可能需要將會話序列化或?qū)⑵鋸?fù)制到其他集群成員,因此將其存儲在 HttpSession 中不是可擴展模式。最好使用 HttpSession 來存儲斷開連接的對象(只要它們非常小,即 10KB 到 50KB),并且在需要更新時,重新將它們與新的 Hibernate 會話關(guān)聯(lián)。這是因為 HttpSession 最適用于書簽,而不適用于緩存。在 Improving HttpSession Performance with Smart Serialization 中討論了如何使 HttpSession 的內(nèi)存使用率降至最低。不是將 HttpSession 用作緩存,而是考慮使用 ObjectGrid 或 DistributedObjectCache 之類的 WebSphere 數(shù)據(jù)緩存技術(shù),這在下一部分進行介紹。
有關(guān)高性能、可擴展應(yīng)用程序的最佳實踐,強烈建議您閱讀 Performance Analysis for Java Websites 一書。
集成二級緩存
Hibernate 會話表示工作單元的范圍。在 Hibernate 會話的生命周期中,Session 接口管理持久性。通常,它通過保持對單一線程有效的一級緩存實例并維護它負責(zé)的映射實體類實例的識別或狀態(tài)做到這一點。在完成工作單元(會話)時釋放緩存。還可以將二級緩存配置為在 SessionFactory 的所有會話之間共享(包括在群集之間共享)。請注意,在 Hibernate 中進行緩存會導(dǎo)致一些需要解決的問題。第一,對于數(shù)據(jù)庫的外部更改或跨群集更改,無法確保緩存的一致性(除非使用識別群集的緩存)。第二,其他層(如數(shù)據(jù)庫)可能已經(jīng)緩存,從而使 Hibernate 緩存的值降至最低。在進行應(yīng)用程序設(shè)計時,必須認真考慮這些問題,但是這些問題超出了本文的討論范圍。
![]() |
|
Hibernate 附帶了幾個預(yù)配置的緩存。在 Hibernate Cache 文檔頁中可以找到關(guān)于這些緩存的信息。對于只讀數(shù)據(jù),一個內(nèi)存緩存可能就足夠了。不過,當(dāng)聚集應(yīng)用程序并需要群集識別緩存時,本地只讀緩存是不夠的。如果需要分布式緩存,我們建議使用 WebSphere 提供的分布式緩存實現(xiàn)之一。可以將它們用作 Hibernate 的二級緩存:
-
DistributedMap / DistributedObjectCache 接口提供支持 WebSphere v6.x 產(chǎn)品系列的分布式緩存。有關(guān)詳細信息,請參見 Using the DistributedMap and DistributedObjectCache interfaces for the dynamic cache。
-
作為 WebSphere Extended Deployment 產(chǎn)品一部分的 ObjectGrid 提供可擴展的對象緩存支持。有關(guān)詳細信息,請參見 ObjectGrid。
在 WebSphere Enterprise Service Bus 和 WebSphere Process Server 中使用 Hibernate
WebSphere Process Server 和 WebSphere Enterprise Service Bus (ESB) 將 Service Component Architecture (SCA) 和 Service Data Objects (SDO) 用作 SOA 的裝配和編程模式。(請參見參考資料,了解關(guān)于 SCA 和 SDO 的更多信息。)SCA 組件不是 Java EE 組件,因此它們沒有資源引用,但是改為依靠服務(wù)和適配器來連接系統(tǒng)。在構(gòu)建 Java SCA 組件時,不能使用資源引用;因此,SCA 組件不能直接使用 Hibernate。
在這種情況下,應(yīng)將 Hibernate 持久性隱藏在某種 Facade 后面。有兩個備選方案:
-
創(chuàng)建本地 EJB 會話 Facade 以包裝 Hibernate 持久性。會話 Facade 提供適配器邏輯,以便將 Hibernate 實體 POJO 映射到服務(wù)數(shù)據(jù)對象并返回。然后集成開發(fā)人員可以使用 EJB 導(dǎo)入調(diào)用會話 Facade,并以緊密耦合方式使用對應(yīng)的服務(wù)質(zhì)量 (QoS) 調(diào)用它。
-
創(chuàng)建 EJB Web 服務(wù)會話 Facade 以包裝 Hibernate 持久性。然后集成開發(fā)人員可以使用 Web 服務(wù)導(dǎo)入調(diào)用持久性的 Web 服務(wù)。這不需要構(gòu)建 POJO 到 SDO 的轉(zhuǎn)換程序,由于目前 SCA 對數(shù)據(jù)類型只使用 SDO。圖 1 說明了使用兩個模式的業(yè)務(wù)流程,但該流程的詳細信息不在本文的討論范圍之內(nèi)。
圖 1. 示例業(yè)務(wù)流程

WebSphere Application Server V6.1 上的 Hibernate JPA API
Hibernate 的 JPA 支持提供 JPA 標(biāo)準(zhǔn)持久性,并且是專有 Hibernate API 的較好備選方案。Hibernate 的 JPA 實現(xiàn)需要基于 Java EE 5 的運行時,因此,它僅在 WebSphere Application Server V6.1 或更高版本上運行。在發(fā)布時,Hibernate 的 JPA 支持不能在 WebSphere z/OS 和 iSeries 平臺上運行。Hibernate 文檔描述了如何使用 Hibernate 的 JPA 實現(xiàn)包裝和部署應(yīng)用程序。
以下各部分將描述不支持的配置和用例。這僅表示當(dāng)前已確定的不支持的場景。其他不支持的場景將在以后確定。
不支持的事務(wù)配置
Hibernate 文檔描述了用于在 WebSphere Application Server 版本 4 和 5 產(chǎn)品上運行的事務(wù)策略配置,但是這些配置使用內(nèi)部 WebSphere 接口,在那些早期版本上不受支持。在上面的事務(wù)策略配置部分中描述了 Hibernate 唯一支持的事務(wù)配置。正如前面所述,這意味著僅在 WebSphere Application Server V6.x 之后(包括 V6.x)的版本和 WebSphere Business Integration Server Foundation V5.1 上支持使用 Hibernate。
不可交互操作的/不可移植的功能
JPA 規(guī)范中的 3.2.4.2 部分描述了可能導(dǎo)致互操作性和潛在的可移植性問題的情況。這與結(jié)合使用延遲加載(即 @Basic(fetch=LAZY)
)和分離對象有關(guān)。將分離對象合并回會話時,JPA 將檢查該對象,并使用任何更改值來更新數(shù)據(jù)存儲。不過,數(shù)據(jù)對象是簡單的 POJO。在分離時,如果部分 POJO 狀態(tài)沒有加載,則在合并回去時可能顯示為已更改。要使它正常工作,供應(yīng)商必須實現(xiàn)特定于其運行時的序列化技術(shù)。這不是互操作的,語義也不能移植。
![]() ![]() |
![]()
|
通常將 Spring 描述為輕量級容器環(huán)境,但是將其描述為用于簡化開發(fā)的框架可能更適當(dāng)。其主要概念是使用依賴項注入 (DI) 和面向方面的編程 (AOP) 來簡化和平穩(wěn)地進行從開發(fā)到測試再到生產(chǎn)的轉(zhuǎn)換。
Spring 框架是一個流行的開放源代碼框架,它由 Interface21, Inc. 根據(jù) Rod Johnson 發(fā)表的關(guān)于依賴項注入 (DI) 的設(shè)計模型開發(fā)。Spring 可以在獨立應(yīng)用程序或應(yīng)用服務(wù)器中使用。由于 Spring 提供的一些服務(wù)通常由應(yīng)用服務(wù)器運行時提供,所以需要認真設(shè)計 Spring 與應(yīng)用服務(wù)器的結(jié)合使用,以避免在 Spring 實現(xiàn)和應(yīng)用服務(wù)器提供的實現(xiàn)之間發(fā)生沖突。
本部分其余內(nèi)容將描述使可能發(fā)生的實現(xiàn)沖突或矛盾點降至最低的用例,還將描述應(yīng)避免的其他矛盾點(如果可能)。
盡管下文的描述中支持在 WebSphere Application Server 上有限使用 Spring,但是 IBM 并不直接支持 Spring。任何人使用 Spring 時都需要按 Spring Product Support page 的描述獲取對它的支持。客戶應(yīng)該保留用于幫助調(diào)試問題的與開放源代碼項目相關(guān)的源。
以下部分將描述 Spring 在 WebSphere Application Server 上的一些使用場景。不過,應(yīng)由客戶負責(zé)確定這些場景是否適合他們的具體情況。IBM 不支持、也不建議使用 Spring。本文僅演示在 WebSphere Application Server 上使用 Spring 的一組場景,并演示必須如何自定義 Spring 才能與 WebSphere Application Server 一起運行。
簡單的 Bean 邏輯容器
使用 Spring 的最常用的場景之一是使用簡單的 Java Bean 類配置并驅(qū)動業(yè)務(wù)邏輯。本文稍后描述的避免了問題的 Spring 應(yīng)用程序在 WebSphere Application Server 中運行時不應(yīng)該有任何問題。Spring documentation page 應(yīng)提供了使用 Spring Bean 構(gòu)建應(yīng)用程序的足夠信息。此處不存在任何特定于 WebSphere 的內(nèi)容。
在 WebSphere 中使用 Spring DAO 框架
下面是關(guān)于在 WebSphere Application Serveruse 上使用 Spring DAO 功能的三個示例:
-
基本型 DAO 用法
WebSphere Application Server 管理在應(yīng)用服務(wù)器執(zhí)行環(huán)境中使用的資源。需要訪問 JDBC 數(shù)據(jù)源之類資源的 Spring 應(yīng)用程序應(yīng)該利用 WebSphere 管理的資源。為此,需要執(zhí)行以下若干步驟。
-
在開發(fā)過程中,應(yīng)該使用資源引用配置 WAR 模塊。例如:
<resource-ref> <res-ref-name>jdbc/springdb</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> <res-sharing-scope>Shareable</res-sharing-scope> </resource-ref>
-
對于 EJB JAR 文件,應(yīng)該在需要訪問數(shù)據(jù)源的每個 EJB 中聲明同一資源引用。
-
然后使用與以下類似的內(nèi)容在 Spring 配置文件中聲明數(shù)據(jù)源 Bean:
<bean id="WASDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:comp/env/jdbc/springdb"/> <property name="lookupOnStartup" value="false"/> <property name="cache" value="true"/> <property name="proxyInterface" value="javax.sql.DataSource"/> </bean>
這將配置 Bean,以便從模塊的配置引用查找數(shù)據(jù)源。注意,jndiName 屬性值匹配與資源引用中聲明的資源引用名稱連接的模式
java:comp/env/
。 -
然后,Spring 應(yīng)用程序可以在適當(dāng)情況下使用數(shù)據(jù)源 Bean。
-
將應(yīng)用程序部署到 WebSphere Application Server 時,必須配置資源提供程序和資源數(shù)據(jù)源,以便由 Spring 應(yīng)用程序資源引用使用。在部署過程中,在模塊的部署描述符中聲明的資源引用將綁定到應(yīng)用服務(wù)器的配置數(shù)據(jù)源。
-
-
事務(wù)型 DAO 用法
在 Spring 中,有許多方法可以驅(qū)動事務(wù)控制下的資源更新。這包括編程形式和聲明形式。聲明形式有注釋形式和非注釋形式。在使用 Spring 事務(wù)支持時,獲得權(quán)限的重要方法是適當(dāng)?shù)嘏渲?Spring 對底層事務(wù)管理器的使用。在 WebSphere Application Server 中,Spring 使用的事務(wù)管理器的唯一支持形式如下:
<bean d="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="autodetectTransactionManager" value="false"/> </bean>
可以將此事務(wù)管理器 Bean 提供給 JdbcTemplate 類,或通過事務(wù)策略的聲明形式利用。有關(guān)為什么這是唯一形式的詳細信息,請參見避免的場景部分。
-
休眠型 DAO 用法
Spring 記錄將 Hibernate 和 Spring 一起使用的基本設(shè)置。在 WebSphere Application Server 環(huán)境中使用 Hibernate 和 Spring 時,有必要將上述對二者的配置要求合并在一起。正如前面所述,在 Spring 和 Hibernate 中使用 JNDI 訪問事務(wù)管理的資源和適當(dāng)配置是必要的。
Spring Web MVC
Spring 的 Web MVC 框架在某一時間內(nèi)一直是其他框架的備選框架。由 WebSphere Application Server 提交、使用和支持的 Web MVC 框架包括 JSF 和 Struts。Spring 參考手冊描述了如何將 Spring 與這些 Web 框架集成。盡管 WebSphere Application Server 支持上面的任何用法,但 IBM 僅為 WebSphere Application Server 附帶的框架提供缺陷支持。
計劃和線程池
如果需要異步運行代碼,那么應(yīng)該使用 WorkManagerTaskExecutor。在 Spring 中,這是唯一使用由 WebSphere Application Server 托管的線程池的 TaskExecutor 實現(xiàn)。其他 TaskExecutor 實現(xiàn)可以啟動非托管線程。有關(guān)非托管線程的詳細信息,請參見避免的場景。
在 WebSphere Application Server 管理控制臺中,通過導(dǎo)航到 Resources => Asynchronous beans => Work managers 可以對 WorkManager 進行設(shè)置。然后可以在 Spring 配置文件中使用資源的 JNDI 名稱來定義 WorkManagerTaskExecutor。
Spring Portlet
Spring Portlet 可以在 WebSphere Portal V6.0 和 WebSphere Application Server V6.1 Portlet 容器中運行。有關(guān) Spring Portlet 的示例集,請參見 Spring Portlet MVC。在 WebSphere Application Server V6.1 Portlet 容器中運行 Portlet 需要創(chuàng)建其他 Web 應(yīng)用程序才能定義 Portlet 的布局和聚合。從 WebSphere Application Server 信息中心可以獲得關(guān)于如何使用 Portlet 聚合器標(biāo)記庫的信息,在文章 探索 WebSphere Application Server V6.1 Portlet 容器: 第 1 部分:Portlet 容器介紹 中的其他補充信息中也可找到。
通常結(jié)合使用 JSF 和 Portlet 進行呈現(xiàn)。關(guān)于如何將 Spring、Hibernate、JSF 和 WebSphere Portal 組合起來運行的信息可以通過文章 Configuring Hibernate, Spring, Portlets, and OpenInSessionViewFilter with IBM WebSphere Portal Server 了解。
已經(jīng)知道以下場景在 WebSphere Application Server 環(huán)境中會出現(xiàn)問題,應(yīng)該避免它。列出這些場景的原因有許多,不過,最常見的原因是 Spring 使用了內(nèi)部 WebSphere 接口。這些內(nèi)部接口的使用破壞了 WebSphere Application Server 保證應(yīng)用程序環(huán)境的完整性和管理應(yīng)用程序資源的能力。應(yīng)該避免使用任何依賴于內(nèi)部 WebSphere 接口的 Spring 功能。
REQUIRES_NEW 和 NOT_SUPPORTED 事務(wù)策略
WebSphere Application Server 為維護數(shù)據(jù)完整性提供了可靠的環(huán)境。它提供此環(huán)境的方法之一是始終確保應(yīng)用程序邏輯在事務(wù)范圍內(nèi)執(zhí)行。在容器將要執(zhí)行業(yè)務(wù)邏輯時,它會檢查事務(wù)狀態(tài)。如果全局事務(wù)不是動態(tài)的,則容器會創(chuàng)建并管理新的 local transaction containment (LTC) 范圍。容器將在業(yè)務(wù)邏輯結(jié)束時完成 LTC,并在任何應(yīng)用程序啟動的全局事務(wù)過程中將它掛起。這可以確保在業(yè)務(wù)邏輯執(zhí)行結(jié)束時總是正確地清除資源。
Spring 為管理事務(wù)提供了機制。不過,它支持的事務(wù)策略超出了通常可以在應(yīng)用程序級別處理的策略集的范圍。具體說來,它為 REQUIRES_NEW 和 NOT_SUPPORTED 的 EJB 容器管理的語義提供它自已的等效支持。這兩個容器管理的策略都需要掛起和恢復(fù)事務(wù)的功能,但是為使用 EJB 容器而保留了此功能(不適當(dāng)?shù)氖褂脮?dǎo)致數(shù)據(jù)完整性問題)。為提供此行為,Spring 使用了內(nèi)部 WebSphere 接口,但不知道它對容器的影響。使用內(nèi)部接口掛起和恢復(fù)事務(wù)將破壞 Web 和 EJB 容器管理資源和 LTC 的功能,并可能使容器處于未知狀態(tài),從而可能導(dǎo)致數(shù)據(jù)損壞。
以下兩個步驟可以避免此場景:
- 不使用需要掛起和恢復(fù)語義的 Spring 事務(wù)策略。
- 不配置 Spring JtaTransactionManager 使其支持掛起和恢復(fù)語義。
第一是應(yīng)用程序設(shè)計時間限制。如果您構(gòu)建應(yīng)用程序,請不要在語義中設(shè)計需要使用 Spring 來掛起和恢復(fù)事務(wù)。如果需要掛起和恢復(fù)語義,請改為使用無狀態(tài)會話 EJB。
第二是部署時間配置約束。如果在 WebSphere Application Server 中部署基于 Spring 的應(yīng)用程序,則該應(yīng)用程序在嘗試使用 Spring 的掛起和恢復(fù)語義時將會失敗。以這種方式失敗比隨機數(shù)據(jù)損壞錯誤要好得多。下面是必須在 WebSphere Application Server 中配置 Spring JtaTransactionManager 的正確方法:
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="autodetectTransactionManager" value="false"/> </bean> |
這將把 transactionManager Bean 配置為使用 UserTransaction API 來控制事務(wù)的開始、提交和回滾。這使得可以不使用掛起和恢復(fù)語義來支持事務(wù)控制。
上面所述的 Spring JtaTransactionManager 用法不支持與現(xiàn)有事務(wù)同步的 Spring 注冊功能。要做到這一點,需要使用 WebSphereTransactionManagerFactoryBean。使用 WebSphereTransactionManagerFactoryBean 的客戶或調(diào)用內(nèi)部事務(wù)管理器接口的任何其他類將不受支持。
JDBC 本機連接
當(dāng)各種 JDBC 操作需要與本機 JDBC 資源交互時,Spring 可提供訪問本機連接的機制。當(dāng)在 JdbcTemplate 類上設(shè)置了 NativeJdbcExtractor 類時,JdbcTemplate 類才可以利用此功能。設(shè)置 NativeJdbcExtractor 類后,當(dāng)與 WebSphere Application Server 一起使用時,Spring 總是向下找到本機 JDBC 連接。這將忽略以下 WebSphere QoS 功能和優(yōu)點:
- 連接處理跟蹤和再關(guān)聯(lián)
- 連接共享
- 事務(wù)狀態(tài)
- 池管理
- 最后的代理事務(wù)參與。
這帶來的另一個問題是 WebSphereNativeJdbcExtractor 類將依賴于內(nèi)部 WebSphere 適配器類。這些內(nèi)部類可能因 WebSphere Application Server 的版本而異,并且以后可能更改,從而中斷依賴于此功能的應(yīng)用程序。
在 WebSphere Application Server 上不支持使用 NativeJdbcExtractor 類實現(xiàn)(例如 WebSphereNativeJdbcExtractor),客戶應(yīng)避免需要它的場景。備選方案是使用 WebSphere Application Server WSCallHelper 類來訪問非標(biāo)準(zhǔn)供應(yīng)商的數(shù)據(jù)源擴展。
類加載器的缺點
Spring 和 WebSphere Application Server 都使用多個開放源代碼項目,遺憾的是,它們共有的項目版本并不總是匹配。應(yīng)該將 Spring 依賴項包裝為應(yīng)用程序的一部分,并且應(yīng)該按照下面的描述設(shè)置服務(wù)器以避免沖突。否則,類加載器可能無法為運行時或應(yīng)用程序加載適當(dāng)?shù)陌姹尽Mǔ#@將導(dǎo)致在日志中出現(xiàn)有關(guān)類的版本不匹配、ClassCastExceptions 或 java.lang.VerifyErrors 等異常。
其中一個示例是使用 Jakarta Commons Logging。配置供應(yīng)用程序使用的 Jakarta Commons Logging (JCL),或者使用不是由應(yīng)用服務(wù)器提供的其他版本的 JCL(例如,使用應(yīng)用程序代碼嵌入的 JCL)需要在 WebSphere Application Server 上進行特定的配置。有關(guān)如何配置部署的應(yīng)用程序,以使用內(nèi)嵌版本的常用技術(shù)的策略,請參見 Integrating Jakarta Commons Logging。請關(guān)注支持網(wǎng)站,了解是否提供了如何在 WebSphere Application Server V6.x 產(chǎn)品上配置內(nèi)嵌 JCL 的更新。這僅僅是沖突的一個示例。其他示例可能包括應(yīng)用程序使用的 JDOM 或特定版本的 JavaMail。不支持將 WebSphere Application Server 的 JAR 文件替換為這些或具有更高版本或不同版本的其他包。
在 WebSphere Application Server 上困擾 Spring 用戶的另一個類加載器問題是 Spring 加載資源的方法。資源可以包括消息綁定之類的內(nèi)容,通過類加載器層次結(jié)構(gòu)和在層次結(jié)構(gòu)中查找資源的各種策略,能夠在非目標(biāo)位置找到使用公共名稱的資源。可以使用 WebSphere Application Server 類加載器查看器來幫助解決此問題。合并資源和包括其他版本的公共庫可能需要應(yīng)用程序?qū)①Y源重命名為唯一的名稱。
非托管線程
某些 Spring 場景可能導(dǎo)致創(chuàng)建非托管的線程。非托管線程對 WebSphere Application Server 是未知的,并且不能訪問 Java EE 上下文信息。此外,它們可以在 WebSphere Application Server 不知道的情況下利用資源,存在管理員不能控制其數(shù)量和資源使用情況的問題,在發(fā)生故障時,它們還阻止應(yīng)用服務(wù)器正常關(guān)機或恢復(fù)資源。應(yīng)用程序應(yīng)該避免導(dǎo)致啟動非托管線程的任何場景:
-
registerShutdownHook
第一種場景是在使用 Spring AbstractApplicationContext 或它的一個子類時。registerShutdownHook 是一個公共方法,它可以創(chuàng)建線程并將其注冊到 Java 虛擬機,以便在關(guān)機時運行以關(guān)閉 ApplicationContext。應(yīng)用程序可以避免這一點,方法是利用從 WebSphere 容器接收的常規(guī)生命周期通知來顯式調(diào)用 ApplicationContext 上的關(guān)閉。
-
入站 JMS 消息
Spring JMS MessageListenerContainer 類利用啟動非托管線程(例如 SimpleAsyncTaskExecutor)的類來偵聽傳入的 JMS 消息。Spring JMS 容器不僅可以啟動非托管線程,而且還可以使用無法由 Java EE 環(huán)境中的應(yīng)用程序調(diào)用的 JMS API。(有關(guān)詳細信息,請參見 Java EE 規(guī)范 J2EE.6.6 部分。)
可以使用 Spring 遠程處理 API 生成 JMS 消息,但是客戶應(yīng)該使用消息驅(qū)動的 Bean 處理傳入的消息,避免使用 Spring JMS MessageListenerContainer。這可以使用容器適當(dāng)?shù)乜刂坪突謴?fù)資源和事務(wù)。
-
JMX 服務(wù)器
應(yīng)用程序應(yīng)避免使用 Spring JMX ConnectorServerFactoryBean,它是啟動非托管線程的另一個類。WebSphere Application Server 已經(jīng)向 JMX 服務(wù)器提供了多個受支持的連接器協(xié)議。應(yīng)用程序可以向 WebSphere Application Server 的 JMX 服務(wù)器注冊 MBean,并對它們進行遠程訪問。
-
非集成的計劃包
Spring 提供或集成了大量的計劃包。只有與 WebSphere Application Server 托管的線程一起使用的 Spring 計劃包是 CommonJ WorkManager 計劃包。其他包(如 quartz 和 JDK Timer)會啟動非托管線程,應(yīng)該避免使用。
-
WeakReferenceMonitor
Spring 為簡化開發(fā) EJB 組件提供了方便的類。請注意,這些方便的類會生成 WeakReferenceMonitor 用來執(zhí)行清除操作的非托管線程。
![]() ![]() |
![]()
|
如果經(jīng)過充分考慮避免了問題場景,則可以在 WebSphere 平臺上以完全支持的方式使用 Hibernate 和 Spring。尤其是,客戶必須確保他們使用這些框架不涉及使用內(nèi)部 WebSphere 接口。獲得 IBM 的 WebSphere Application Server 支持的用戶如果在將 WebSphere Application Server 和 Spring 或 Hibernate 一起使用時遇到問題,可以獲得 IBM 的幫助來診斷問題,除非問題被確認為使用了不支持的場景,或不是 WebSphere Application Server 的問題。客戶應(yīng)該按照相應(yīng)項目網(wǎng)絡(luò)上的說明自行從其他公司獲得對 Hibernate 和 Spring 框架的支持。
![]() ![]() |
![]()
|
作者非常感謝 Ian Robinson、Keys Botzum、Paul Glezen、Thomas Sandwick、Bob Conyers 和 Neil Laraway,他們對本文提出了寶貴意見。
- 您可以參閱本文在 developerWorks 全球站點上的 英文原文 。
-
developerWorks 上關(guān)于使用 Hibernate 的文章
-
Hibernate Project Support page
-
在 WebSphere Application Server V5 中共享連接
-
Improving HttpSession Performance with Smart Serialization
-
Performance Analysis for Java Websites
-
Hibernate Cache
-
Using the DistributedMap and DistributedObjectCache interfaces for the dynamic cache
-
ObjectGrid
-
Spring Product Support page
-
Spring Portlet MVC
-
探索 WebSphere Application Server V6.1 Portlet 容器: 第 1 部分:Portlet 容器介紹
-
Configuring Hibernate, Spring, Portlets, and OpenInSessionViewFilter with IBM WebSphere Portal Server
-
本地事務(wù)容器
-
Integrating Jakarta Commons Logging
- WSCallHelper
![]() |
||
|
![]() |
Tom Alcott 是 IBM 美國的一位 IT 咨詢專家。自 1998 年 Worldwide WebSphere Technical Sales Support 小組成立以來,他就一直是該小組的成員。在此期間,他花費了大多數(shù)時間來編寫用戶手冊。在開始研究 WebSphere 之前,他是 IBM 的 Transarc 實驗室的一名系統(tǒng)工程師,負責(zé)支持 TXSeries。他有 20 多年從事基于大型機和分布式系統(tǒng)的應(yīng)用程序設(shè)計與開發(fā)工作的背景。他撰寫并發(fā)表了大量關(guān)于 WebSphere 運行時問題的文章。 |
![]() |
||
|
![]() |
Roland Barcia 是位于紐約/新澤西地區(qū)的IBM WebSphere 軟件服務(wù)部的一位認證 IT 專家。他是 IBM WebSphere: Deployment and Advanced Configuration 的合著者之一。有關(guān) Roland 的詳細信息,請訪問他的網(wǎng)站。 |
![]() |
||
|
![]() |
Jim Knutson 是 WebSphere 的 J2EE 架構(gòu)師。Jim 負責(zé) IBM 參與的 J2EE 相關(guān)規(guī)范,他參與這些工作的時間要追溯到 J2EE 出現(xiàn)以前。Jim 還參與了編程模型的改進,以支持 SOA 和 Web 服務(wù)。 |