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

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