首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring 與 Hibernate 在 WebSphere Application Server 上的整合最佳實踐指南

     編輯:Java 相關知識

前言

IBM WebSphere Application Server (WAS) 為企業級 Java EE 容器,提供健全的事務、安全、執行緒、連線池管理。本文針對 Spring Framework 2.5+ 與 Hibernate 於 WAS V7/V8/V9 環境的整合,提供經實戰驗證的配置最佳實踐,避開常見類別載入衝突、事務管理陷阱與非受管執行緒風險。

一、Spring 整合關鍵配置

1. 資料源:必須使用 WAS 管理的 JNDI DataSource

Web 模組 web.xml / EJB 模組 ejb-jar.xml 宣告 resource-ref:

<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>

Spring XML 以 JndiObjectFactoryBean 或 <jee:jndi-lookup> 代理:

<jee:jndi-lookup id="wasDataSource"
    jndi-name="jdbc/springdb"
    cache="true"
    resource-ref="true"
    lookup-on-startup="false"
    proxy-interface="javax.sql.DataSource"/>

關鍵:resource-ref="true" 讓 Spring 自動補上 java:comp/env/ 前綴,確保查找受容器管理的資源。

2. 事務管理:使用 WebSphereUowTransactionManager

Spring 2.5+ 提供 org.springframework.transaction.jta.WebSphereUowTransactionManager,委派 WAS UOWManager 介面,支援完整傳播行為(含 REQUIRES_NEW、NOT_SUPPORTED)。

<bean id="transactionManager"
    class="org.springframework.transaction.jta.WebSphereUowTransactionManager"/>

<tx:annotation-driven transaction-manager="transactionManager"/>

禁用:JtaTransactionManager (autodetectTransactionManager=false) 僅支援有限傳播行為;WebSphereTransactionManagerFactoryBean 依賴內部 SPI,不受支援。

3. JMS 整合:受管 ConnectionFactory + WorkManagerTaskExecutor

<jee:jndi-lookup id="jmsConnectionFactory" jndi-name="jms/myCF" resource-ref="true"/>

<bean id="jmsQueueTemplate" class="org.springframework.jms.core.JmsTemplate">
  <property name="connectionFactory" ref="jmsConnectionFactory"/>
  <property name="destinationResolver" ref="jmsDestResolver"/>
</bean>

<bean id="msgListenerContainer"
    class="org.springframework.jms.listener.DefaultMessageListenerContainer">
  <property name="connectionFactory" ref="jmsConnectionFactory"/>
  <property name="destination" ref="jmsQueue"/>
  <property name="messageListener" ref="messageListener"/>
  <property name="transactionManager" ref="transactionManager"/>
  <property name="taskExecutor" ref="workManagerTaskExecutor"/>
</bean>

<bean id="workManagerTaskExecutor"
    class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">
  <property name="workManagerName" value="wm/default"/>
</bean>

注意:生產環境高可用/負載管理場景,建議直接使用 J2EE MDB 替代 Spring Message-driven POJO。

4. JPA 整合:直接使用 JPA,勿用 Spring JPA Helper

persistence.xml 設定 JTA 資料源與 OpenJPA managed 模式:

<persistence-unit name="default" transaction-type="JTA">
  <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
  <jta-data-source>java:comp/env/jdbc/springdb</jta-data-source>
  <properties>
    <property name="openjpa.TransactionMode" value="managed"/>
    <property name="openjpa.ConnectionFactoryMode" value="managed"/>
    <property name="openjpa.jdbc.DBDictionary" value="db2"/>
  </properties>
</persistence-unit>

EntityManager 注入:@PersistenceContext EntityManager em; + PersistenceAnnotationBeanPostProcessor。

5. 排程與執行緒池:只用 WorkManagerTaskExecutor

Quartz、JDK Timer、Spring 其他 TaskExecutor 皆會啟動非受管執行緒,違反 Java EE 規範,導致資源洩漏、無法優雅關閉。WAS 管理主控台配置 WorkManager (Resources → Asynchronous beans),Spring 僅注入 JNDI 名稱。

6. JMX MBean 註冊:實作 ObjectNamingStrategy

WAS MBean ObjectName 為完整限定名稱 (WebSphere:cell=...,name=...,type=...)。實作 ObjectNamingStrategy 封裝命名邏輯,注入 MBeanExporter,確保應用卸載時正確取消註冊。

7. 類別載入器隔離:PARENT_LAST + 共享庫策略

  • 應用內打包 Spring/Hibernate/Commons Logging 等依賴 JAR
  • WAR 模組類別載入器設為 PARENT_LAST (模組級) 或 EAR 級 PARENT_LAST 配合 Classloader isolation
  • 避免替換 WAS 內建 JAR (JDOM, JavaMail 等)
  • 資源檔衝突:重新命名或使用獨特套件路徑

二、Hibernate 整合關鍵配置

1. SessionFactory 使用 WAS DataSource

<property name="hibernate.connection.datasource">java:comp/env/jdbc/myDSRef</property>

2. 事務策略:CMT 或 BMT 搭配 WebSphereExtendedJTATransactionLookup

<!-- CMT 容器管理事務 -->
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.CMTTransactionFactory</property>
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WebSphereExtendedJTATransactionLookup</property>

<!-- BMT 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>

支援 WAS V6.0.2.19+ / V6.1.0.9+。舊版內部介面配置不受支援。

3. Session 模式:優先「每請求一 Session」

OpenSessionInViewFilter 搭配 Spring 事務,避免長會話序列化/叢集複寫問題。HttpSession 僅存放極小斷離物件 (10-50KB),大型快取改用 ObjectGrid / DistributedObjectCache。

4. 二級快取:整合 WAS 分散式快取

  • 實作 org.hibernate.cache.CacheProvider 介面包裝 DistributedMap / DistributedObjectCache 或 ObjectGrid
  • 設定 hibernate.cache.provider_class 指向自訂實作
  • 識別叢集快取 (Hibernate 內建) 行為未定,生產環境勿直接使用

5. 多隔離等級:為每個等級建立獨立 DataSource + SessionFactory

可共享連線不支援動態切換隔離等級。

三、WebSphere Process Server / ESB 特殊場景

SCA 組件無 resource-ref,無法直接用 Hibernate。兩種門面模式:

  1. 本地 EJB Session Facade:包裝 Hibernate,實體 POJO ↔ SDO 轉換,EJB Import 呼叫
  2. EJB Web Service Facade:包裝 Hibernate 暴露為 Web Service,Web Service Import 呼叫

四、避坑清單與支援邊界

禁忌後果正確做法
使用 NativeJdbcExtractor / WebSphereNativeJdbcExtractor繞過連線池/事務/追蹤,依賴內部類會隨補丁失效用 WSCallHelper 存取廠商擴充 API
Spring registerShutdownHook啟動非受管執行緒,阻礙優雅關閉用 ServletContextListener / @PreDestroy 生命週期回調
WeakReferenceMonitor (Spring EJB 便利類)產生非受管執行緒避免使用,自行管理 EJB 引用
Quartz / JDK Timer / SimpleAsyncTaskExecutor非受管執行緒改用 WorkManagerTaskExecutor
直接使用 WAS 內部 SPI (com.ibm.*)升級風險極高,不受 IBM 支援僅用公開 Java EE / Spring / WAS 公開 API

五、IBM 支援立場

  • 遵循本文建議配置,遇到 WAS 本身缺陷,IBM 提供產品支援。
  • 開放原始碼框架修補服務,建議向社群或合作夥伴尋求。
  • 本文非官方支援聲明,最終以 IBM Support Handbook 為準。

結語

Spring + Hibernate 在 WebSphere 上穩健運行的關鍵在於:尊重容器契約——資源由容器管理、事務由容器協調、執行緒由容器調度、類別載入隔離避免衝突。將框架配置對齊 Java EE 規範與 WAS 公開 API,即可同時享受 Spring 開發效率與 WAS 企業級可靠性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved