歡迎您光臨本站 註冊首頁

將 Spring 和 Hibernate 與 WebSphere Application Server 一起使用

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
  

引言

Spring Framework(通常稱為 Spring)是一個開放源代碼項目,目的是為了使 J2EE™ 環境更具可訪問性。Spring 為簡單 Java™ 對象提供框架,使這些對象可以通過包裝類和 XML 配置使用 J2EE 容器。Spring 的目標是為這些項目提供顯著的好處,提高這些項目的開發效率和運行時性能,同時改進測試覆蓋率和應用程序質量。

Hibernate 是開放源代碼持久性和查詢框架,提供傳統 Java 對象(Plain Old Java Object,POJO)到關係資料庫表的對象-關係映射,以及數據查詢和檢索功能。

儘管許多組織感興趣的是了解使用這些框架能夠獲得什麼好處,但 IBM 希望讓使用這些框架的客戶知道,他們可以通過 WebSphere Application Server 以穩健和可靠的方式做到這一點。本文介紹這些框架如何與 WebSphere Application Server 一起使用,並介紹針對各種用例的最佳實踐,以幫助您儘快開始使用 Spring 或 Hibernate。





使用 Spring

通常將 Spring 描述為輕量級容器環境,但是將其描述為用於簡化開發的框架可能更適當。Spring Framework 由 Interface21 根據 Rod Johnson 發表的關於依賴項注入設計模式的出版物開發而成。Spring 可以在獨立應用程序中使用,或與應用程序伺服器一起使用。其主要概念是使用依賴項注入和面向方面的編程來簡化和平穩地進行從開發到測試再到生產的轉換。

涉及 Spring 的最常用場景之一是使用簡單的 Java Bean 類配置並驅動業務邏輯。 Spring 文檔應該提供了使用 Spring Bean 構建應用程序的足夠信息,其中沒有提供任何特定於 WebSphere 的內容。以下部分將描述在 WebSphere Application Server 上使用 Spring 的一些使用場景。根據本文的建議開發的 Spring 應用程序應該能夠毫無問題地在 WebSphere Application Server 或 WebSphere Application Server Network Deployment 環境中執行。

除明確指出以外,本文提供的信息適用於所有平台上的 WebSphere Application Server 版本 6.0.2.x、6.1.x 和 7.0.x。

表示層注意事項

本部分介紹與在基於 Web 的表示層中使用 Spring 相關的注意事項。

  • Web MVC 框架

    Spring 的 Web MVC 框架很長時間以來一直是其他框架的替代框架。直接由 WebSphere Application Server 交付、使用和支持的 Web MVC 框架包括 JavaServer Faces (JSF) 和 Struts。Spring 文檔描述了如何將 Spring 與這些 Web 框架集成。儘管 WebSphere Application Server 支持使用上面的任何 MVC,但 IBM 僅為 WebSphere Application Server 附帶的框架提供產品支持。

  • Portlet MVC 框架

    Spring 還提供了一個 Portlet MVC 框架(該框架鏡像 Spring Web MVC 框架),而且在 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 容器介紹中可以獲得關於如何使用 Portlet 聚合器標記庫的信息。通常的做法是結合使用 JSF 和 Portlet 進行呈現。關於如何將 Spring、Hibernate、JSF 和 WebSphere Portal 組合起來的信息,請參見使用 IBM WebSphere Portal 配置 Hibernate、Spring、Portlets 和 OpenInSessionViewFilter。

數據訪問注意事項

本部分介紹與訪問事務中的數據的 Spring Bean 配置相關的注意事項。

Spring Framework 實際上使用一個容器管理層(在 J2EE 環境中委託給基礎 J2EE 運行時)包裝 Spring Bean。下面將介紹應如何配置 Spring Bean,以便 Spring Framework 可以正確地向 WebSphere Application Server 運行時做出委託並與之集成。

  • 訪問 WebSphere Application Server 中配置的數據源

    WebSphere Application Server 管理在應用程序伺服器執行環境中使用的資源。需要訪問諸如 JDBC 數據源等資源的 Spring 應用程序應該利用 WebSphere 管理的資源。為此,請執行以下步驟:

    1. 在開發過程中,應該使用資源引用配置 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>  

    2. 對於 EJB JAR 文件,應該在需要訪問數據源的每個 EJB 中聲明同一資源引用。

    3. 然後在 Spring 應用程序配置中聲明數據源代理 Bean,代理 Bean 引用 WebSphere 管理的資源提供者:

      <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 訪問數據源將會導致使用模塊配置的引用查找數據源,從而能夠由 WebSphere Application Server 正確管理。請注意,jndiName 屬性值與使用資源引用中聲明的資源引用名稱連接的模式 java:comp/env/ 匹配。

      或者,在 Spring 2.5 以後的版本中,可以使用 <j2ee:jndi-lookup/> 方法完成此匹配。請注意 jndiName 屬性如何匹配資源引用中聲明的資源引用名稱與 resource-ref="true" 屬性相結合的實際值:

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

    4. 然後,Spring 應用程序可以在適當情況下使用數據源代理 Bean。

    5. 將應用程序部署到 WebSphere Application Server 時,必須以常規方式配置資源提供者和資源數據源,以便由 Spring 應用程序資源引用使用。在部署過程中,在模塊的部署描述符中聲明的資源引用將綁定到應用程序伺服器配置的數據源。

  • 使用 JDBC 本機連接

    當各種 JDBC 操作需要與本機 JDBC 資源交互時,Spring 可提供訪問本機連接的機制。當在 JdbcTemplate 類上設置了 NativeJdbcExtractor 類時,Spring JdbcTemplate 類才可以利用此功能。設置 NativeJdbcExtractor 類后,當與 WebSphere Application Server 一起使用時,Spring 總是向下找到本機 JDBC 連接。這將忽略以下 WebSphere 服務質量功能和優點:

    • 連接處理跟蹤和再關聯
    • 連接共享
    • 參與事務
    • 連接池管理

    這帶來的另一個問題是 WebSphereNativeJdbcExtractor 類將依賴於內部 WebSphere 適配器類。這些內部類可能因 WebSphere Application Server 的版本而異,並且以後可能更改,從而破壞依賴於此功能的應用程序。

    在 WebSphere Application Server 上不支持使用 NativeJdbcExtractor 類實現(例如 WebSphereNativeJdbcExtractor),您應避免需要使用該類的場景。替代方案是使用 WebSphere Application Server WSCallHelper 類來訪問非標準供應商的數據源擴展。

  • 使用 Spring 處理事務

    WebSphere Application Server 為事務處理和管理與資源提供者的連接提供了一個穩健和可伸縮的環境。無論是否在使用全局事務,與 JDBC、JMS 和 Java Connector 資源適配器的連接均由 WebSphere Application Server 管理;甚至在缺少全局事務時,始終存在一個運行時上下文,在該上下文中可以訪問所有資源提供者連接。WebSphere Application Server 將此運行時上下文稱為本地事務容器 (LTC) 作用域;在缺少全局事務時始終存在一個 LTC,並且無論是存在全局事務還是 LTC,資源訪問始終由運行時管理。為確保事務上下文管理的完整性,以便可以正確管理事務資源,WebSphere Application Server 不向 WebSphere Application Server 中部署的應用程序或應用程序框架公開 javax.transaction.TransactionManager 介面。

    在 Spring 中,有許多方法可以驅動事務控制下的資源更新,這包括編程形式和聲明形式。聲明形式包括 Java Annotation 和 XML 描述符形式。如果將 Spring 2.5 與 WebSphere Application Server V6.0.2.19 或 V6.1.0.9 或者更高版本一起使用,則可以利用對 Spring 的聲明式事務模型的完全支持。Spring 2.5 有一個新的用於 WebSphere Application Server 的 PlatformTransactionManager 類,名為 WebSphereUowTransactionManager。該類利用 WebSphere Application Server 的受支持 UOWManager 介面進行事務上下文管理。通過 WebSphere Application Server 的 UOWManager 類管理事務劃分可以確保在訪問資源提供者時始終可以使用適當的全局事務或 LTC 上下文。不過,早期版本的 Spring 使用了內部 WebSphere 介面,以犧牲 Web 和 EJB 容器功能為代價來管理資源,並且不支持由應用程序使用。這會使容器處於未知狀態,從而有可能導致數據損壞。

    Spring 2.5 或更高版本中的聲明式事務劃分在 WebSphere Application Server 中受支持,它使用下面的聲明提供對 WebSphere 事務的支持:

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

    引用此聲明的 Spring Bean 然後將使用標準 Spring 依賴項注入來使用事務支持,例如:

    <bean id="someBean" class="some.class">  	<property name="transactionManager" >  		<ref bean="transactionManager"/>  	</property>  ...  </bean>  <property name="transactionAttributes">  	<props>  		<prop key="*">PROPAGATION_REQUIRED</prop>  	</props>  	</property>

    或者,在 Spring 2.5 以後的版本中,可以利用 Spring 的 AspectJ 支持。在下面的示例中,可以將 <tx:advice/> 應用於應用程序的各個部分。這指示所有以“get”開頭的方法都是 PROPAGATION_REQUIRED,並且所有以“set”開頭的方法都是 PROPAGATION_REQUIRES_NEW。所有其他方法使用預設事務設置。

    <tx:advice id="txAdvice" transaction-manager="transactionManager">     <tx:attributes>        <tx:method name="get*" propagation="REQUIRED" read-only="true" />        <tx:method name="set*" propagation="REQUIRES_NEW" />        <tx:method name="*" />     </tx:attributes>  </tx:advice>

    <aop:config/> 標記將那些設置應用於類 MyService 中定義的任何已執行操作。

    <aop:config>     <aop:pointcut id="myServiceOperation"         expression="execution(* sample.service.MyService.*(..))"/>     <aop:advisor advice-ref="txAdvice"         pointcut-ref="myServiceOperation"/>  </aop:config>

    用於聲明事務設置的另一種替代機制是使用基於 Spring 註釋的事務支持。這要求使用 Java 5+,因此無法與 WebSphere Application Server V6.0.2.x 一起使用。

    將以下內容添加到 Spring.xml 配置:

    <tx:annotation-driven/>

    然後應該使用 @Transactional 註釋對需要事務屬性的任何方法進行標記:

    @Transactional(readOnly = true)  public String getUserName()  { ...

    請注意,只能將 @Transactional 註釋用於註釋公共方法。

    WebSphereUowTransactionManager 支持每個 Spring 事務屬性:

    • PROPAGATION_REQUIRED
    • PROPAGATION_SUPPORTS
    • PROPAGATION_MANDATORY
    • PROPAGATION_REQUIRES_NEW
    • PROPAGATION_NOT_SUPPORTED
    • PROPAGATION_NEVER

    對於沒有提供 org.springframework.transaction.jta.WebSphereUowTransactionManager 的早期 Spring 版本以及沒有提供 com.ibm.wsspi.uow.UOWManager 的 WebSphere Application Server V6.0.2.19 或 V6.1.0.9 之前的版本,WebSphere Application Server 中的事務支持通過以下 Spring 配置實現:

    <bean id="transactionManager"   	class="org.springframework.transaction.jta.JtaTransactionManager">  		<property name="autodetectTransactionManager"value="false" />  </bean>

    此配置支持一組受限制的事務屬性,其中不包括 PROPAGATION_NOT_SUPPORTED 和 PROPAGATION_REQUIRES_NEW。Spring 類 org.springframework.transaction.jta.WebSphereTransactionManagerFactoryBean 也宣稱提供 PROPAGATION_NOT_SUPPORTED 和 PROPAGATION_REQUIRES_NEW 功能,它使用不受支持的內部 WebSphere Application Server 介面,不應將其與 WebSphere Application Server 一起使用。

  • 使用 Spring JMS

    與訪問 JDBC 數據源類似,打算訪問 JMS 目的地的 Spring 應用程序必須確保它們使用了 WebSphere 管理的 JMS 資源提供者。使用 Spring JndiObjectFactoryBean 作為 ConnectionFactory 代理的相同模式將確保可以正確地管理 JMS 資源。

    對於 JMS 消息發送或同步 JMS 消息接收,可以使用 JMSTemplates。這包括通過 JNDI 和真正的動態解析使用 Spring 的動態目的地解析功能。

    下面的示例演示了 ConnectionFactory 的資源引用配置。此引用在應用程序部署過程中映射為指嚮應用程序伺服器的 JNDI 命名空間中存儲的已配置託管 ConnectionFactory。ConnectionFactory 是執行消息處理所必需的,並且應該將其注入 Spring JMSTemplate。

    <resource-ref>        <res-ref-name>jms/myCF</res-ref-name>        <res-type>javax.jms.ConnectionFactory</res-type>        <res-auth>Container</res-auth>        <res-sharing-scope>Shareable</res-sharing-scope>  </resource-ref>

    現在應用程序中的 ConnectionFactory 有了已定義的 JNDI 名稱,可以對其進行查找並將其注入 JMSTemplate:

    <jee:jndi-lookup id="jmsConnectionFactory" jndi-name=" jms/myCF "/>    <bean id="jmsQueueTemplate"            class="org.springframework.jms.core.JmsTemplate">    <property name="connectionFactory">        <ref bean="jmsConnectionFactory"/>     </property>     <property name="destinationResolver">        <ref bean="jmsDestResolver"/>     </property>      ...  </bean>    <!-- A dynamic resolver -->  <bean id="jmsDestResolver" class="         org.springframework.jms.support.destination.DynamicDestinationResolver"/>    <!-- A JNDI resolver -->  <bean id="jmsDestResolver"   	class=" org.springframework.jms.support.destination.JndiDestinationResolver"/>

    在運行時,JMSTemplate 可以基於目的地的 JNDI 名稱(在應用程序資源引用中配置)或通過“動態解析”來基於 WebSphere Application Server 中配置的目的地的管理名稱定位目的地;例如,對於綁定到 jms/myQueue 的 JNDI 引用的 JMS myQueue 隊列:

    JNDI 解析:
    jmsTemplate.send("java:comp/env/jms/myQueue", messageCreator);

    動態解析:
    jmsTemplate.send("myQueue", messageCreator);

    作為對 J2EE 消息驅動 Bean (MDB) 的替代,Spring 提供了用於非同步地處理入站 JMS 消息的消息驅動 POJO 模型。僅有一個 DefaultMessageListenerContainer 類將管理從 JMS 隊列到已配置的 POJO 的消息,該 POJO 必須是 javax.jms.MessageListener 實現。

    在 WebSphere Application Server 環境中,您還必須指定一個 WorkManagerTaskExecutor 類,這意味著 DefaultMessageListenerContainer 類將向伺服器管理的線程池作出委託。正如上面描述過的,還應該通過 WebSphereUowTransactionManager 使用伺服器的事務管理來配置 DefaultMessageListenerContainer。

    <bean id="messageListener" class="sample.ExampleMessageListener" />       <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="myTaskExecutor" />     </bean>       <bean id="myTaskExecutor"        class="org.springframework.scheduling.commonj.WorkManagerTaskExecutor">        <property name="workManagerName" value="wm/default" />     </bean>       <bean id="transactionManager"        class="org.springframework.transaction.jta.WebSphereUowTransactionManager" />       <jee:jndi-lookup id="jmsConnectionFactory" jndi-name="jms/CF1" />       <jee:jndi-lookup id="jmsQueue" jndi-name="jms/jmsQueue" />

    雖然可以使用此消息驅動 POJO 模型,但是在需要工作負載管理和/或高可用性的 WebSphere Application Server 配置中,建議直接使用 J2EE 消息驅動 Bean (MDB)。請注意,不支持任何其他 Spring JMS MessageListenerContainer 類型,因為它們可以啟動非託管線程,而且還可能使用不應由 Java EE 環境中的應用程序調用的 JMS API。

  • 將 JPA 與 Spring 一起使用

    EJB 3.0 規範將 Java Persistence API (JPA) 定義為提供可移植持久 Java 實體的方法。WebSphere Application Server V7 和 WebSphere Application Server V6.1 EJB 3 功能包都提供了 EJB 3 和 JPA 的實現;還可以將 JPA 的 Apache OpenJPA 實現與 WebSphere Application Server V6.1 一起使用(請參見參考資料)。將 Spring 與 JPA 實現結合使用時,您應該直接使用 JPA,而不是使用 Spring 的 JPA Helper 類(在 org.springframework.orm.jpa 包中)。

    WebSphere Application Server V6.1 及更高版本支持 JPA 應用程序託管的實體管理器,該管理器可能是 JTA 或本地資源事務類型。JTA 實體管理器使用應用程序伺服器的基礎 JTA 事務支持,其事務劃分可以使用上面描述的標準 J2EE 技術或 Spring 的聲明式事務模型進行定義。

    使用 JPA 的數據訪問對象 (DAO) 與 persistence.xml 打包在一起,後者為應用程序使用的 JPA EntityManager 定義持久性上下文。例如,可以按下面的方式設置用於 JTA 實體管理器(使用的數據源的 JNDI 名稱為“java:comp/env/jdbc/springdb”)的 persistence.xml:

    <persistence      xmlns="http://java.sun.com/xml/ns/persistence"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence     http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">  	<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>  </persistence>

    通過將 openjpa.TransactionMode 和 openjpa.ConnectionFactoryMode 屬性設置為“managed”,JPA 實體管理器將事務和連接管理委託給 WebSphere Application Server。DAO 可以使用上面描述的 Spring 聲明式事務劃分。

    還可以使用註釋風格的 JPA EntityManager 注入。這與標準 JPA 完全相同:

    @PersistenceContext  private EntityManager em;

    您需要以下 XML 代碼將在 Spring XML 配置中啟用 EntityManager 注入:

    <!-- bean post-processor for JPA annotations -->  <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>  |--10--------20--------30--------40--------50--------60--------70--------80--------9|  |-------- XML error:  The previous line is longer than the max of 90 characters ---------|  

    Spring 將在此 XML 文件中定義的 EntityManagerFactory 的基礎上創建 EntityManager 。如果存在多個 EntityManagerFactory,則 Spring 將失敗。使用以下方法中的一種(且僅一種)方法創建 EntityManagerFactory:

    • 使用 Spring 的基本配置
      <bean id="entityManagerFactory"        class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">     <property name="persistenceUnitName" value="default"/>  </bean>

    • 使用 Spring 的高級配置
      <bean id="myEmf"   	class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">  |-------20--------30--------40--------50--------60--------70--------80--------9|  |-------- XML error:  The previous line is longer than the max of 90 characters ---------|    <property name="dataSource" ref="ds"/>  </bean>    <jee:jndi-lookup       id="ds"       jndi-name="jdbc/ds"       cache="true"       expected-type="javax.sql.DataSource"  />

    當然,通過使用 WebSphere Application Server V7 和 WebSphere Application Server V6.1 EJB 3 Feature Pack 中的純粹 EJB 3 支持也可以獲得註釋和 JPA 的優點。在任一種情況下,您都可以使用 JPA API 創建 EntityManagerFactory,如下所示。建議不要將此方法用於非 EJB 3 環境,因為可能無法正確管理所創建的任何 EntityManager。但是,當您擁有 EJB 3 環境時,可以使用此方法分離 Spring 和 JPA 配置。

    <bean id="myEmf"      class="javax.persistence.Persistence"      factory-method="createEntityManagerFactory" >    <constructor-arg type="java.lang.String" value="default"/>    </bean>

  • IBM JDK 6

    WebSphere Application Server V7 在 IBM JDK 6 上運行,由於已在此 JIRA 中作文檔說明的 Spring 問題,無法將 IBM JDK 6 與 V2.5.5 以前的 Spring 框架一起使用。

集成和管理注意事項

  • JMX 和 MBean

    僅當 Spring JMX MBean 向 WebSphere Application Server 的容器管理器 MbeanServer 註冊后,WebSphere Application Server V6.1 和更高版本才支持它。如果不指定任何伺服器屬性,則 MBeanExporter 將嘗試自動檢測運行的 MbeanServer。因此,在 WebSphere Application Server 上運行應用程序時,Spring 框架將找到容器的 MbeanServer。

    您不應使用 MBeanServerFactory 實例化 MbeanServer,然後將其注入 MbeanExporter。而且,WebSphere Application Server 不支持使用 Spring 的 ConnectorServerFactoryMBean 或 JMXConnectorServer 通過打開入站 JMX 埠將本地 MBeanServer 公開給客戶端。

    WebSphere Application Server Version 6.1 以前的版本不支持 Spring JMX Mbean。

  • 在 WebSphere Application Server 中註冊 Spring MBean

    當按下面的方式註冊時,WebSphere Application Server MBean 將由 javax.management.ObjectName 標識:

    WebSphere:cell=99T73GDNode01Cell,name=JmxTestBean,node=99T73GDNode01,
    process=server1,type=JmxTestBeanImpl

    這意味著,如果它們被取消註冊,則需要使用相同的“完全限定”名稱(而不是 MBean 的簡單名稱屬性)查找它們。最好的方法是實現 org.springframework.jmx.export.naming.ObjectNamingStrategy,它是封裝 ObjectName 實例創建的介面,並且在註冊 Bean 時,MBeanExporter 可以使用它獲得 ObjectName。Spring Framework 論壇上提供了一個示例。可以將 ObjectNamingStrategy 實例添加到您註冊的 Bean。這可以確保在卸載應用程序時正確地取消註冊 MBean。

    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"     lazy-init="false">  <property name="beans">  	<map> <entry key="JmxTestBean" value-ref="testBean" /> </map>  </property>  <property name="namingStrategy" ref="websphereNamingStrategy" />  ...  </bean>

     

  • MBean ObjectName 和通知

    由於在 WebSphere Application Server 中使用的是 MBean 的完全限定 ObjectName,因此建議您完整定義該 ObjectName 以使用通知。此 JIRA 支持改為使用 Spring Bean 名稱,,但是僅當您在使用相應版本的 Spring 的時候,才應該提供修復程序。

    <bean id="exporter" class="org.springframework.jmx.export.MBeanExporter"      lazy-init="false">  	<property name="beans">  		<map>  		  <entry key="JmxTestBean" value-ref="testBean" />  		</map>  	</property>  	<property name="namingStrategy" ref="websphereNamingStrategy" />  	<property name="notificationListenerMappings">  		<map>  		  <entry key="WebSphere:cell=99T73GDNode01Cell, name=JmxTestBean,  			node=99T73GDNode01, process=server1, type=JmxTestBeanImpl">  			  <bean class="client.MBeanListener" />  		  </entry>  		</map>  	</property>  </bean>

  • System z 多調用/單調用限制

    由於 Spring 不允許在 MBean 描述符中指定特定於平台的欄位,因此 Spring JMX 將在 WebSphere Application Server V6.1 中的多 SR 伺服器上運行,但在部署選項中受限。WebSphere Application Server 預設使用單調用策略,這樣僅要求一個 MBean 實例(在一個不確定的 SR 中)就可以執行某個請求。在某些場景中這已足夠,但是應用程序更可能需要能夠聲明多調用和單調用方法的組合,並且可能產生聚合邏輯。

  • 調度和線程池

    Spring 提供了許多可用於調度工作的 TaskExecutor 類。只有 WebSphere Application Server 支持用於非同步執行工作的 Spring TaskExecutor 才是 Spring WorkManagerTaskExecutor 類,該類可正確地利用 WebSphere Application Server 託管的線程池,並向已配置的 WorkManager 作出委託。其他 TaskExecutor 實現可以啟動非託管線程。

    在 WebSphere Application Server 管理控制台中,可以通過導航到 Resources => Asynchronous beans => Work managers 對 WorkManager 進行設置。然後可以在 Spring 配置文件中作為 workManagerName 屬性使用資源的 JNDI 名稱來定義 WorkManagerTaskExecutor。下面的示例使用 WebSphere Application Server 的 DefaultWorkManager JNDI 名稱或 wm/default:

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

  • 類載入器

    Spring 和 WebSphere Application Server 都使用多個開放源代碼項目,遺憾的是,它們共有的項目版本並不總是匹配。應該將 Spring 依賴項包裝為應用程序的一部分,並且應該按照下面的描述設置伺服器以避免衝突。否則,類載入器可能無法為運行時或應用程序載入適當的版本。通常,這將導致異常,在日誌中顯示類、ClassCastExceptions 或 java.lang.VerifyErrors 的版本不匹配。

    其中一個示例是使用 Jakarta Commons Logging。要配置供應用程序使用的 Jakarta Commons Logging (JCL),或者使用不是由應用程序伺服器提供的其他版本的 JCL(例如,使用應用程序代碼嵌入的 JCL),將需要在 WebSphere Application Server 上進行專門的配置。有關如何配置已部署的應用程序,以使用嵌入版本的常用技術的策略,請參見集成 Jakarta Commons Logging。請密切關注支持網站,了解是否提供了有關如何在 WebSphere Application Server V6.x 產品上配置嵌入式 JCL 的更新。這僅僅是衝突的一個示例。其他示例可能包括應用程序使用 JDOM 或特定版本的 JavaMail。不支持將 WebSphere Application Server 的 JAR 文件替換為這些或具有更高版本或不同版本的其他包。

    在 WebSphere Application Server 上困擾 Spring 用戶的另一個類載入器問題是 Spring 載入資源的方法。資源可以包括消息綁定之類的內容,通過類載入器層次結構和在層次結構中查找資源的各種策略,可以在非預期的位置找到使用公共名稱的資源。可以使用 WebSphere Application Server 類載入器查看器來幫助解決此問題。資源與其他版本的公共庫的組合可能要求應用程序將資源重命名為唯一的名稱。

    James Estes 在 Spring 論壇上闡述的示例包含打包為 EAR 文件的 EJB 項目和 Web 項目。所描述的解決方案是將 spring.jar 文件同時添加到 WEB-INF/lib 和頂級 EAR 中,然後將 WEB 項目的類載入器策略設置為 PARENT LAST,以便先找到 WEB-INF/lib 中的版本。EJB 項目使用 EAR 中的版本。

設計注意事項

Spring Framework 提供的某些基礎結構服務將複製由基於標準的應用程序伺服器運行時提供的服務。而且,從基礎 J2EE 應用程序伺服器抽象出 Spring 框架基礎結構必然要削弱與應用程序伺服器運行時服務質量的集成,如安全性、工作負載管理和高可用性。因此,在應用程序設計過程中,必須認真考慮部署到 WebSphere Application Server 中的應用程序中的 Spring Framework 使用,以避免降低 WebSphere Application Server 提供的任何服務質量。如果沒有任何其他建議,首選的方法是直接使用 WebSphere Application Server 提供的服務,以便基於開放標準開發應用程序,並確保未來部署的靈活性。

  • 非託管線程

    某些 Spring 場景可能導致創建非託管的線程。非託管線程對 WebSphere Application Server 是未知的,並且不能訪問 Java EE 上下文信息。此外,它們可以在 WebSphere Application Server 不知道的情況下利用資源,在管理員無法控制其數量和資源使用的情況下存在,在發生故障時,它們還阻止應用程序伺服器正常關閉或恢復資源。應用程序應該避免導致啟動非託管線程的任何場景,如:

    • registerShutdownHook

      避免使用 Spring AbstractApplicationContext 或其子類之一。registerShutdownHook 是一個公共方法,它可以創建線程並將其註冊到 Java 虛擬機,以便在關機時運行以關閉 ApplicationContext。應用程序可以避免這一點,方法是利用從 WebSphere 容器接收的常規生命周期通知來顯式調用 ApplicationContext 上的關閉。

    • WeakReferenceMonitor

      Spring 為簡化開發 EJB 組件提供了方便的類,但是請注意,這些方便的類會生成由 WeakReferenceMonitor 用來執行清除操作的非託管線程。

  • 調度

    Spring 提供(或集成)了大量的調度包,但是,只有與 WebSphere Application Server 託管的線程一起使用的 Spring 調度包才是 CommonJ WorkManager。其他包(如 quartz 和 JDK Timer)會啟動非託管線程,應該避免使用。





使用 Hibernate

Hibernate 是用於 POJO 的開放源代碼持久性框架,它通過 XML 配置文件提供 POJO 到關係資料庫表的對象-關係映射。Hibernate 框架是應用程序調用來實現數據持久性的數據訪問抽象層。此外,Hibernate 還提供了從 Java 類到資料庫表(以及從 Java 數據類型到 SQL 數據類型)的映射,以及數據查詢和檢索功能。Hibernate 生成必需的 SQL 調用,還負責結果集處理和對象轉換。

Hibernate(如 OpenJPA)實現了 Java Persistence API (JPA) 規範,此規範是 Java EE 5 的必備組成部分。(有關如何使用 Hibernate 的 developerWorks 文章,請參見參考資料。)

使用場景

以下場景描述了有關如何將 Hibernate 與 WebSphere Application Server 和 WebSphere 產品堆棧結合使用的一些可能場景。這些僅是示例場景,不應認為是推薦的場景。

  • 使用 WebSphere Application Server 數據源

    為了讓 Hibernate 從 WebSphere Application Server 獲取資料庫連接,必須使用 Java EE(以前稱為 J2EE)規範中強制規定的資源引用。這可以確保 WebSphere Application Server 能夠為連接池、事務語義和隔離級別提供正確的行為。通過將 hibernate.connection.datasource 屬性(在 Hibernate 配置文件中進行了定義)設置為引用在模塊的部署描述符中定義的資源引用(例如 java:comp/env/jdbc/myDSRef),將 Hibernate 配置為從 WebSphere Application Server 檢索數據源。例如:

    <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 介面建立了一種在 Java EE 5 中通過 JTA 1.1 規範正式確立的模式。

  • 不支持的事務配置

    Hibernate 文檔描述了用於在 WebSphere Application Server 版本 4 和 5 產品上運行的事務策略配置,但是這些配置使用內部 WebSphere 介面,在早期版本上不受支持。上面僅描述了受支持的 Hibernate 事務配置,如前面所述,這意味著僅在 WebSphere Business Integration Server Foundation V5.1 和 WebSphere Application Server Version 6.x 以及更高版本上支持使用 Hibernate。

  • WebSphere Application Server 環境中的 Hibernate 使用模式

    當結合使用 Hibernate 和 WebSphere Application Server 時,Hibernate 的“按請求會話”和“長時間對話”模式均可使用。客戶必須選擇適用於其應用程序的模式,不過我們主張使用“按請求會話”模式,因為它可以提供更好的可擴展性。

    • 多個隔離級別

      可共享的連接通過讓多個資源用戶能夠共享現有的連接,在 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 最適用於書籤,而不適用於緩存。在使用智能序列化改進 HttpSession 性能中討論了如何使 HttpSession 的內存使用率降至最低。與將 HttpSession 用作緩存不同,應該考慮使用 ObjectGrid 或 DistributedObjectCache 之類的 WebSphere 數據緩存技術,這在下一部分進行介紹。

    有關高性能、可擴展應用程序的最佳實踐,強烈建議您閱讀 Performance Analysis for Java Websites 一書。

在本文發表之際,Hibernate 的識別集群的緩存與 WebSphere Application Server 相結合的行為還沒有確定,因此,還不能確定是否支持使用該緩存,我們對此不做進一步的討論。因此,需要分散式緩存的客戶應當考慮創建使用屬性 hibernate.cache.provider_class 實現 org.hibernate.cache.CacheProvider 的類,該屬性將採用 WebSphere 中的兩個分散式緩存實現中的一個。
  • 集成二級緩存

    Hibernate 會話表示工作單元的範圍。在 Hibernate 會話的生命周期中,Session 介面管理持久性。通常,它通過保留對單個線程有效的一級緩存實例,維護它負責的映射實體類實例的可識別性或狀態,從而做到這一點。該緩存在工作單元(會話)完成時消失。還可以將二級緩存配置為在 SessionFactory 的所有會話之間共享(包括在集群之間共享)。請注意,在 Hibernate 中進行緩存會導致一些需要解決的問題。第一,對於資料庫的外部更改或跨集群更改,無法確保緩存的一致性(除非使用識別集群的緩存)。第二,其他層(如資料庫)可能已經緩存,從而使 Hibernate 緩存的價值降至最低。在進行應用程序設計時,必須認真考慮這些問題,但是這些問題超出了本文的討論範圍。

    Hibernate 附帶了幾個預配置的緩存。在 Hibernate 緩存文檔頁中可以找到關於這些緩存的信息。對於只讀數據,一個內存緩存可能就足夠了。不過,當對應用程序進行集群並需要識別集群的緩存時,本地只讀緩存是不夠的。如果需要分散式緩存,我們建議使用 WebSphere 提供的分散式緩存實現之一。可以將它們用作 Hibernate 的二級緩存:

    • DistributedMap/DistributedObjectCache 介面提供了支持 WebSphere v6.x 產品系列的分散式緩存。有關詳細信息,請參見將 DistributedMap 和 DistributedObjectCache 介面用於動態緩存。

    • 作為 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 SE 5 的運行時,因此僅在 WebSphere Application Server V6.1 或更高版本上運行。在本文發表之際,Hibernate 的 JPA 支持不能在 WebSphere System z 和 iSeries 平台上運行。Hibernate 文檔描述了如何使用 Hibernate 的 JPA 實現包裝和部署應用程序。

  • 不可交互操作/不可移植的功能

    JPA 規範中的 3.2.4.2 部分描述了可能導致互操作性和潛在的可移植性問題的情況。這與結合使用延遲載入(即 @Basic(fetch=LAZY))和分離對象有關。將分離對象合併回會話時,JPA 將檢查該對象,並使用任何更改值來更新數據存儲區。不過,數據對象是簡單的 POJO。在分離時,如果部分 POJO 狀態沒有載入,則在合併回去時可能顯示為已更改。要使它正常工作,供應商必須實現特定於其運行時的序列化技術。這不是可互操作的,語義也可能不是可移植的。





產品和客戶技術支持

用戶合理關注的領域是對使用開放源代碼的項目的支持,以及使用開放源代碼對供應商支持其許可產品的影響。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 支持手冊和 WebSphere Application Server 支持聲明。

儘管在開放源代碼環境中使用 WebSphere Application Servers 時按照本文建議的做法有助於增強您的體驗,但本文並沒有列出開放源代碼組件影響 WebSphere Application Server 操作或其他組件操作的所有情況。使用開放源代碼的用戶務必檢查所有組件的規範,以避免出現許可、支持和技術問題。

本文中的術語“支持”或“受支持”指示描述的用法僅限於使用 IBM 有文檔記錄的功能。作者盡最大努力提供關於如何配置和使用這些框架的建議,以確保其用法與有文檔記錄的產品行為一致,但本文不是保證,也不是 Spring 或 Hibernate 的支持聲明。





結束語

Spring Framework 正在迅速普及。開發人員喜歡使用易用的介面和基於 XML 的配置加速 J2EE 開發和輕鬆地進行單元測試。框架本身也正在迅速發展,現在,網站上列出了許多子項目。與使用所有軟體一樣,確定在應用程序中使用它可以提供什麼好處,以及是否具有實現相同結果的更好替代方法是非常重要的。當然,Spring 中的一些功能複製了已嵌入 WebSphere Application Server 的功能,所以將署到該伺服器中的應用程序使用此額外的框架代碼層是不可取的。但是,如果使用得當,您可以將 Spring 的許多易用的開發功能與 WebSphere Application Server 可靠的集成企業支持功能結合使用,以快速開發企業應用程序,並將其部署到 IBM 中行業領先的 J2EE 應用程序伺服器。

Hibernate 是可以與 WebSphere Application Server 一起成功使用的多個持久性框架之一,可以提供到關係資料庫中存儲的實體數據的對象-關係映射(前提是足夠小心地避免有問題的場景)。特別是,您必須確保使用 Hibernate 不涉及使用內部 WebSphere Application Server 介面。按照這裡提供的建議,您可以避免一些常見問題,並將 Hibernate 用作部署到 WebSphere Application Server 的應用程序的持久性框架。(責任編輯:A6)



[火星人 ] 將 Spring 和 Hibernate 與 WebSphere Application Server 一起使用已經有1570次圍觀

http://coctec.com/docs/linux/show-post-68996.html