熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

JBoss 4.0 簡化了中間件的開發

2013-11-23 20:07:52  來源: Java開源技術 

  概要

  JBoss 應用程序服務器(AS)不僅是一個通過JEE認證的應用程序服務器而且也是多種領先優勢開源技術的一個融結點這些技術簡化了基於POJO的中間件應用的開發模型而且將成為下一代JEE標准在這篇文章中Dr Michael 除了探究了JBoss AS 中的新特性之外還給你預覽了明日將出現什麼//

  在年的九月JBoss應用服務器(AS) 通過了JEE 的認證對於JBoss的核心開發人員和JBoss早期的采用者JBoss AS 最振奮的並不是JEE的認證而是目前JEE無法涵蓋的新技術和極大地簡化Java中間件開發的目標就是使用更加簡單的更加易於管理的POJO來替代已存在的EJB的理念簡化程序將提高開發人員的效率更好的程序性能和更少的Bug簡單化(aka 輕量級開發)將是服務器端Java社區下一個重大的事件JBoss AS 將是第一個在該方面邁出堅實步伐的JEE主流服務器

  這篇文章中我將用三個示例程序來展示JBoss AS 中POJO中間件框架的簡單性以及他們是如何與當前和明日的JEE規范關聯起來的如果你是一個JBoss的用戶或者一個普通的JEE開發人員這篇文章將教你一些不僅在目前的JBoss AS 和將來的JBoss 或者 JEE 服務器上可以應用的輕便技巧

  讓我們從目前EJB 中間件框架中固有的問題開始來展示對一個更加簡單的基於POJO框架的需要

  (開源和JEE規范――對於Java社區和開源社區來說JBoss的官方JEE認證是一個具有裡程碑意義的事件因為不久之前由於高成本和所要求的大量的保證質量的工作人們認為如果Sun不發慈悲的話任何開源的JEE項目都不可能通過認證的JBoss 僅僅依靠自己就獲得了JEE的認證證明了開源開發模型在交付迅速的企業Java解決方案的正確性)

  (一)EJB 出了什麼問題了?

  開始的時候JEE 在開發具有伸縮性和分布性的服務器端應用市場獲得了巨大的成功然而EJB在JEE裡的一個核心的開發中間件的構件卻獲得了一個太復雜和難用的名聲特別是對於中小型業務應用的開發額外的EJB基礎代碼和部署描述符不僅使服務器資源承擔不起而且更加重要的是降低了開發人員的效率導致開發人員最終寫更多了和需要維護更多的基礎代碼而不是業務邏輯

  為了證明以上觀點 和提供一個JBoss AS 支持的更加簡單的解決方案的選擇性的比較讓我們來看一個基於EJB 的示例程序抵押金計算器Web應用程序先計算每個月每筆貸款的抵押金將結果保存到一個關系數據庫裡每次計算之後該程序在數據庫中之前的結果中搜索所需數額較低的抵押金那些結果將在頁面的底部顯示 展示了該程序如何工作的當你初次使用該程序的時候你將被要求填入一個用戶名和密碼使用user / pass登錄如果你想看到顯示給未授權用戶的錯誤信息請嘗試 user/pass

  

  圖 實戰抵押金計算器web應用

  從示例源碼包ejb文件夾可以獲取該程序的源代碼在ejb目錄 (Windows)只要執行buildbat命令或者buildsh命令(Linux Unix 或者Mac OS X系統)來重建該應用將生成的ejb/build/jar/MortgageCalculatorEJBear文件拷貝到JBoss 服務器的server/default/deploy/部署訪問該應用的URL將是

  //localhost/MortgageCalculatorEJB/servlet/Calculator

  為何要使用EJB?

  對一個如此簡單的應用為什麼使用EJB?EJB容器提供了一些有用的服務無須我們寫其他代碼這些服務可以立即增加一些企業性的特性給我們的web應用例如EJB會檢查用戶的信任度對於所有的EJB方法的調用容器將根據配置文件監控其相關的數據庫事務另外容器也管理者數據庫的表和數據庫連接所有這些都無須我們寫任何的SQL或者JDBC代碼

  在該分支下嘛Web應用有一個servlet接受用戶的輸入同時產生HTML頁面Servlet將押金計算和數據庫相關的工作分派給一個EJB模塊來完成

  該應用有兩個EJB構件Calculator bean是一個無狀態的會話bean它包含了計算押金的保存結果到數據庫的搜索數據庫的事務性的方法這些方法都曝露給了servlet

  Calculator bean使用了History實體bean訪問數據庫在EJB的配置文件裡我們定義了History實體bean的數據域是如何映射到數據庫的列的對於一系列的History對象如何搜索數據庫由於History bean是一個EJB它無法在EJB容器外使用所以我們創建了HistoryList 值對象來保持任何的搜索操作結果將返回給servlet

  圖闡明了EJB模塊的結構它展示了所有需要的EJB組成接口和部署描述符的要素

  resized image

  圖 EJB模塊的重要構件

  如你所看到的在圖中展示的結構是復雜的包括了幾個緊耦合的Java接口和史前的XML如果一個框架允許開發人員專注於他們所擅長的—也就是寫Java代碼—而不是用一堆構件接口和XML轉移他們的注意力那該多好啊!好消息是

  JBoss AS 中的POJO中間件框架使開發人員很好的利用EJB容器的服務而沒有EJB的包袱

  (二)簡單化的創新

  從使用EJB危險中我們認識到一個成功的可選框架應該具有以下重要特性

  該框架不應該給開發人員增加任意的構件模型因為這些模型會打破面向對象的設計結構換句話來說該框架應該支持一些開發人員可以對其擴展和在應用容器內部或者外部重用的POJO

  該框架應該摒棄需要手工編寫大量冗余的EJB部署描述符一個POJO應該可以以簡單的聲明它需要什麼樣的容器服務

  該框架應該支持通過引用對POJO進行本地訪問Java對象序列化是緩慢的在允許的時候應該避免使用特別是對於小型到中型的應用更加需要避免

  在過去的幾年Java開源社區並沒有等待Java社區過程(JCP)去發明或者標准化一個基於POJO的輕量級的中間件框架而是已經實驗了無數的方法這些開源的項目的例子包括了XDoclet Hibernate Spring和一些面向方面的編程(AOP)項目JBoss 中的新的中間件框架補充了過去的研究和開發努力

  兩個JBoss贊助的開源項目在它的POJO中間件框架中扮演了重要的角色

  JBoss AOP項目支持了通過Java注解把服務傳輸給POJO

  Hibernate項目是對象關系映射和POJO持久化實際上的標准框架

  為了支持企業級的應用兩個項目都集成和強化了經過檢驗的和通過JEE認證的JBoss AS容器服務現在讓我們重構抵押金計算器EJB構件成為POJO看看這個強大的新開發模型是如何工作的

  企業POJO的強大之處

  POJO抵押金計算器應用也包含在源碼包裡就如我將要說明的該應用的源代碼和創建腳本對於JSE 和JSE 環境有稍微的不同我准備了兩個版本分別存放在pojojdk pojojdk目錄裡創建和部署的命令跟ejb樣例應用都是一樣的一旦部署了訪問POJO樣例的URL將是

  //localhost/MortgageCalculatorPOJO/servlet/Calculator

  就如我講論述的我們的目標是使用POJO替代會話和實體bean期間該框架應該能夠保持EJB服務器的一個關鍵的好處—聲明應用容器服務給應用程序這樣的話當我們今後需要改變容器服務的時候我們僅僅需要修改聲明而且無須修改大量的Java代碼但是無須部署描述符一個POJO如何告知JBoss容器它需要什麼服務呢?這就是AOP和Java注解表演的地方了

  重用注解

  注解是從JSE 開始引入為官方Java語言語義的一部分JBoss AS 定義了一套注解標簽作為POJO訪問JEE容器服務的API並且聲明了容器服務是如何應用的在該分支下JBoss AS使用了JBoss AOP框架來動態改變被注解的對象和方法的行為從JBoss AOP的用戶指導和參考文檔你可以找到更多關於JBoss AOP的信息和它是如何與注解一道運作的

  以下列出了替代了Calculator會話Bean的Calculator POJO類的基本骨架
@SecurityDomain (other)
public class Calculator {

  @Unchecked
  public Calculator () {
  }

  @Permissions ({AuthorizedUser})
  @Tx (TxTypeREQUIRED)
  public double getPayment (int principal double rate
                            int term) throws Exception {
                            
    // Calculate and save to database
    // Code omitted for clarity
  }

  @Permissions ({AuthorizedUser})
  @Tx (TxTypeREQUIRED)
  public List getHistory (double payment) throws Exception {

    // Search the database
    // Code omitted for clarity
  }
}

  @SecurityDomain 注解聲明了該POJO的安全域是other該域告知了JBoss從classpath的usersproperties 和rolesproperties文件裡尋找密碼和用戶角色列表@Permissions注解指定了只有用戶名為AuthorizedUser的用戶才可以訪問getPayment()和getHistory()方法JBoss AS將在運行時進行權限檢查@Tx 注解將為getPayment()和getHistory()方法啟動JBoss事務管理器確保它們對數據庫作出的任何修改都必須在整個方法成功地執行和返回的情況下才提交

  但是JEE 的用戶又該如何做?他們也能使用簡單的POJO作為EJB的選擇?答案是一個響亮的是!你可以在JEE源碼裡嵌入類似Javadoc風格注釋的注解JBoss AOP框架提供了一個注解編譯器該編譯器後續執行那些Java注釋並且把注解增加到字節碼裡這個編譯器的功能就類似於XDoclet下面所列出的展示了在pojojdk目錄的JEE版本的Calculator POJO類
   /**

* @@orgjbossaspectssecuritySecurityDomain (other)
*/
public class Calculator {

  /**
    * @@orgjbossaspectssecurityUnchecked
    */
  public Calculator () {
  }

  /**
    * @@orgjbossaspectssecurityPermissions ({AuthorizedUser})
    * @@orgjbossaspectstxTx (orgjbossaspectstxTxTypeREQUIRED)
    */
  public double getPayment (int principal double rate
                            int term) throws Exception {
                            
    // Calculate and save to database
    // Code omitted for clarity
  }

  /**
    * @@orgjbossaspectssecurityPermissions ({AuthorizedUser})
    * @@orgjbossaspectstxTx (orgjbossaspectstxTxTypeREQUIRED)
    */
  public List getHistory (double payment) throws Exception {

    // Search the database
    // Code omitted for clarity
  }
}


  要使用JBoss AOP注解編譯器你僅需要在Ant的建造腳本裡增加一個任務以下列出了pojojdk/buildxml 腳本中相關的部分
<target name=prepare>
    
    

    <taskdef name=annotationc
           classname=orgjbossaopantAnnotationC
           classpat />
  </target>
  
  
  
  <target name=annotate depends=compile>
    <annotationc compilerclasspat
                 classpath=${builddir}/classes
                 bytecode=true>
      <src path=${srcdir}/>
    </annotationc>
  </target>

  有了Java注解我們用一個簡單的POJO替代了會話bean和其相關的構件但是實體又怎麼辦?

  輕量級的POJO持久化

  容器管理持久化實體bean的主要功能是模擬應用數據和保持其對後端數據庫的持續透明在JBoss AS 中輕量級的中間件框架Hibernate完成了數據的模擬和持久化

  History類是一個在計算事務中模擬數據的簡單POJO它僅包含了數據域和JavaBean風格的訪問方法
public class History {

  private int id;
  private int principal;
  private double rate;
  private int term;
  private double payment;

  public History () {
  }

  public History (int principal double rate
                  int term double payment) {
    thisprincipal = principal;
    thisrate = rate;
    thisterm = term;
    thispayment = payment;
  }

  public int getId () {
    return id;
  }

  public void setId (int id) {
    thisid = id;
  }

  public int getPrincipal () {
    return principal;
  }

  public void setPrincipal (int principal) {
    thisprincipal = principal;
  }

  public double getRate () {
    return rate;
  }

  public void setRate (double rate) {
    thisrate = rate;
  }


  public int getTerm () {
    return term;
  }

  public void setTerm (int term) {
    thisterm = term;
  }

  public double getPayment () {
    return payment;
  }

  public void setPayment (double payment) {
    thispayment = payment;
  }
}

  現在我們需要一個名為Historyhbmxml 得Hibernate映射文件將History類映射到一個數據庫表將數據字段映射到數據庫表的列裡
<hibernatemapping>
  <class name=comjbossMortgageCalculatorpojoHistory
         table=history>
    <id name=id type=int column=id>
      <generator class=increment />
    </id>

    <property name=principal
              type=int column=principal/>

    <property name=rate
              type=double column=rate/>

    <property name=term
              type=int column=term/>

    <property name=payment
              type=double column=payment/>
  </class>
</hibernatemapping>

  但是我們還沒指定用哪個後端數據庫和如何與JBoss Server容器集成我們在hibernateservicexml裡指定這些設置
<server>
    <mbean code=orgjbosshibernatejmxHibernate
           name=jbosshar:service=Hibernate>
        <attribute name=DatasourceName>
          java:/DefaultDS
        </attribute>
        <attribute name=Dialect>
          netsfhibernatedialectHSQLDialect
        </attribute>
        <attribute name=SessionFactoryName>
          java:/hibernate/SessionFactory
        </attribute>
        <attribute name=CacheProviderClass>
          netsfhibernatecacheHashtableCacheProvider
        </attribute>
        <attribute name=HbmddlAuto>
          createdrop
        </attribute>
    </mbean>
</server>

  要在JBoss AS中部署Hibernate模塊我們比較將其打包進一個har後綴的jar文件裡hibernateservicexml文件必須要放到har壓縮文件裡的METAINF目錄裡以下列出了打包該har文件在Ant 建造腳本裡的相關任務
<target name=packagehar depends=annotate>
    <jar jarfile=${builddir}/jar/calculatorpojohar>
      <metainf dir=dd/har includes=**/*xml />
      
      <fileset dir=${builddir}/classes>
        <include name=com/jboss/MortgageCalculator/pojo/**/>
        <include name=*properties/>

      </fileset>
    </jar>
  </target>

  JBossHibernate集成的魔力

  Hibernate模塊模擬了業務數據透明的將Java數據對象和關系數據庫表相互映射但是我們怎麼在Calculator對象裡使用該Hibernate POJO呢?

  在一個正規的Hibernate應用裡你必須獲得一個SessionFactory創建一個Session啟動一個事務然後在該事務內部干你自己的工作工作完成後你必須提交(或者回滾)該事務以及關閉該session

  然而在JBoss AS內部你無須上述框架代碼JBoss透明的處理所有Hibernate服務

  對於抵押金計算器POJO應用我們僅僅需要從一個HibernateContext工廠類獲得一個Hibernate Session對象該工廠類要通過使用配置在har模塊hibernateservicexml文件中 JNDI(Java命名目錄接口)名稱獲得就像我們看到的Hibernate事務是自動的與容器中的事務服務綁定的容器服務又是通過@Tx注解標簽啟動的你無須關閉該事務或者該會話JBoss將決定是否提交改變和清理會話

  以下列出的展示了在Calculator POJO類裡的Hibernate相關代碼hsesssave()語句保存一個Hibernate POJO到數據庫hsessfind()語句查詢數據庫獲得一系列的History POJO
public class Calculator {

  /**
    * @@orgjbossaspectssecurityUnchecked
    */
  public Calculator () {
  }

  /**
    * @@orgjbossaspectssecurityPermissions ({AuthorizedUser})
    * @@orgjbossaspectstxTx (orgjbossaspectstxTxTypeREQUIRED)
    */
  public double getPayment (int principal double rate
                            int term) throws Exception {
    rate = rate / ;
    rate = rate / ;
    double tmp = Mathpow(+rate term);
    tmp = (principal * tmp * rate) / (tmp );

    // Save this calculation into the database
    // Notice that it is automatically associated
    // with the AOP transaction We do not even need
    // to close the session!
    try {
      History history = new History (principal
          rate * term tmp);
      Session hsess =
          HibernateContextgetSession(
              java:/hibernate/SessionFactory);
      hsesssave (history);

    } catch (Exception e) {
      eprintStackTrace ();
      // The new exception triggers the tx rollback
      throw new Exception (Saving failed!);
    }

    return tmp;
  }

  /**
    * @@orgjbossaspectssecurityPermissions ({AuthorizedUser})
    * @@orgjbossaspectstxTx (orgjbossaspectstxTxTypeREQUIRED)
    */
  public List getHistory (double payment) throws Exception {

    List result = null;
    try {
      Session hsess =
          HibernateContextgetSession(
              java:/hibernate/SessionFactory);
      result = hsessfind (
          from History as h where hpayment < ?
          new Double(payment) HibernateDOUBLE);

    } catch (Exception e) {
      eprintStackTrace ();
      // The new exception triggers the tx rollback
      throw new Exception (Finding failed!);
    }
    return result;
  }
}

  總結闡明了抵押金計算器POJO應用的結構與圖 EJB 模型比較形成鮮明對比的盡管對於一個像我們這樣一個的小應用POJO模型是多麼的簡單

  resized image

  圖 POJO模塊中的關鍵構件

  (三)前瞻EJB

  基於POJO中間件的理念植根於開源項目現在它正朝著JEE的標准化邁進即將來臨的由JSR(Java 規范要求)專家組開發的EJB 規范將使用POJO作為EJB的構件並將在諸多場合摒棄部署文件的需要作為一個開源的主角簡單化POJO模型的倡議者JBoss是EJB 背後驅動力的一員

  EJB 編程模型和API類似於JBoss AS 的POJO模型因而移植JBoss AS POJO應用和相關的開發技術到未來的EJB服務器將被證明是簡單的

  如果今日你想與明日的EJB 技術共舞你可以從JBoss 上下載和安裝JBoss AS 的EJB 預覽版模塊JBoss EJB 預覽實現是基於JBoss AOP和Hibernate的預覽版軟件基於EJB 的一份草案並將受將來變化的影響

  核對你的JBoss版本

  請確保你有安裝正確JBoss版本支持EJB 模塊例如JBoss EJB 預覽模塊僅僅與JBoss AS RC一起工作當新的EJB預覽版本發行的時候這將受其影響你可以在EJB 模塊的安裝文檔裡找到最新的信息

  為了展示EJB 的如何工作的我將使用EJB 的API重新實現抵押金計算器應用你可以在EJB源碼目錄建造一旦部署訪問EJB 應用的URL將是

  //localhost/MortgageCalculatorEJB/servlet/Calculator建造該EJB 應用JSE 是必須的

  如下代碼所示Calculator接口聲明了基於POJO的會話Bean@local注解標簽指定了EJB 會話Bean與其客戶(即Servlet 模塊)部署在同一個JVM上因此Servlet將通過它的Java引用訪問該會話Bean也就避免了緩慢對象序列化操作如果會話Bean在不同的服務器上運行你可以在該接口上加注@remote標簽
@Local
public interface Calculator {

  public double getPayment (int principal double rate int term);

  // Get previous queries that has payment lower than
  // the current one
  public List getHistory (double payment);

}

  CalculatorBean類是會話Bean的實現我們用@stateless標簽將其聲明為一個無狀態的會話Bean
@Stateless
@SecurityDomain(other)

public class CalculatorBean implements Calculator {

  @Inject
  private EntityManager manager;

  public CalculatorBean () {  }

  @MethodPermissions({AuthorizedUser})
  @Tx(TxTypeREQUIRESNEW)
  public double getPayment (int principal double rate int term) {
    rate = rate / ;
    rate = rate / ;
    double tmp = Mathpow(+rate term);
    tmp = (principal * tmp * rate) / (tmp );

    HistoryBean history =
        new HistoryBean (principal rate * term tmp);
    managercreate (history);

    return tmp;
  }

  @MethodPermissions({AuthorizedUser})
  @Tx(TxTypeREQUIRESNEW)
  public List getHistory (double payment) {

    return managercreateQuery(
        from HistoryBean h where hpayment < :payment)
        setParameter(payment new Double(payment))
        listResults();
  }
}

  HistoryBean類是對數據庫進行持久化的數據模型查看一下我們如何用注解來避免對對象數據庫表映射文件的需要的另外EntityManager替代了POJO樣例裡的HibernateContext對象運行時注解將EntityManger對象注入HistoryBean對象因此我們無須與JNDI設置和命名糾纏
@Entity
@Table(name = history)
public class HistoryBean {

  private int id;
  private int principal;
  private double rate;
  private int term;
  private double payment;

  public HistoryBean () {
  }

  public HistoryBean (int principal double rate
                      int term double payment) {
    thisprincipal = principal;
    thisrate = rate;
    thisterm = term;
    thispayment = payment;
  }

  @Id(generate = GeneratorTypeAUTO)
  public int getId () {
    return id;
  }

  public void setId (int id) {
    thisid = id;
  }

  public int getPrincipal () {
    return principal;
  }

  public void setPrincipal (int principal) {
    thisprincipal = principal;
  }

  public double getRate () {
    return rate;
  }

  public void setRate (double rate) {
    thisrate = rate;
  }


  public int getTerm () {
    return term;
  }

  public void setTerm (int term) {
    thisterm = term;
  }

  public double getPayment () {
    return payment;
  }

  public void setPayment (double payment) {
    thispayment = payment;
  }
}

  總的來說除了EJB 實體Bean模型相對基於Hibernate的POJO模型簡單用EJB 寫就的應用與JBoss AS 的POJO應用是相似的 顯示了基於 EJB 的抵押金計算器應用的結構

   

  圖 EJB 模塊中的關鍵構件


From:http://tw.wingwit.com/Article/program/Java/ky/201311/27980.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.