<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評論 - 101, 引用 - 0
    數據加載中……

    用 EJB3.0 簡化 EJB 開發

    討論

      引入 Enterprise JavaBeans ( EJB ) 是為了構建分布式組件。最初 , 該技術承諾可以解決 CORBA 的所有問題并降低其復雜性。作為J2EE的核心,EJB經歷了幾次較大的修訂,并加入了許多特性,因而變得臃腫起來。從一開始,大部分開發人員就非常鐘愛EJB,甚至在沒有任何意義的情況下也在其應用程序中使用EJB。當項目不能正常擴展,又在使用EJB時,很多開發人員都會責怪EJB。

      EJB 開發從來就沒有變得更為容易 , 相反 , 隨著 EJB 規范的相繼發布 , 它還變得越來越復雜了。由于其復雜性和本身龐大的體系,EJB被喻為一頭大象。許多開發人員認為EJB就像油炸圈餅外邊多的一層糖。在狂熱奉行低糖飲食和低碳水化合物的年代,EJB專家委員會別無選擇,只能努力提供“低糖”的EJB,以簡化EJB的開發。EJB 3.0專家委員會在JavaOne 2004會議期間發布了 EJB 3.0規范 的第一個公開草案,并給出了一個輕量級模型的示例圖片。

      新的 EJB 模塊 給人的第一感覺是看上去很漂亮 , 在本文中 , 我們將討論 EJB 3.0 如何把自己包裝得更為小巧玲瓏 , 從而吸引開發人員的眼球。在接下來的另一篇文章里,我們將討論EJB3.0如何簡化持久性模型。

    EJB 模型的復雜性

      在開始討論EJB 3.0帶來的新特性之前,讓我們了解一下當前 EJB 模型的復雜性。

    • 當前的 EJB 模型 需要創建若干個組件接口并實現若干個不必要的回調方法。
    • 這些組件接口需要實現 EJB Object 或 EJB LocalObject , 且需要處理許多不必要的異常情況。
    • EJB 部署描述符復雜 , 且易出錯。
    • 容器管理的持久性基于 EJB 模型 , 也十分復雜 , 不利于開發和管理。缺乏一些基本功能(如按標準方法使用數據庫序列定義主鍵等),且 EJBQL 十分受限。
    • 由于有繼承性和多態性方面的約束 , EJB 組件與其源對象并不相同。
    • EJB 的主要缺點之一就是不能在 EJB 容器外測試 EJB 模塊 ,而且 對開發人員而言 , 要在容器內調試 EJB 是件可怕的事。
    • 如果用過 EJB , 您就會知道查找和調用 EJB 的有多復雜了。為了在應用程序中使用 EJB ,您必須了解 JNDI 的每個細節。

    簡化開發人員視圖

      如果用過最新的規范開發 EJB , 就會發現開發一個類似于 HelloWorldEJB 這樣簡單的 EJB 有多困難。您至少需要兩個接口、一個bean類和一個部署描述符。大多數開發人員都在想:我要這些干什么?在 Oracle JDeveloper Eclipse XDoclet 等IDE中,開發人員可以輕松地完成這些瑣事,不過,在將EJB部署到所選的容器之前,開發人員仍需負責編譯這些類并包裝部署描述符。

      EJB 3.0希望使用以下方法來克服這種復雜性:

    • 無需使用接口和部署描述符 , 而是由容器使用元數據標注生成。
    • 將 普通 Java 類用作 EJB ,將 普通業務接口用于EJB。

    元數據標注

      EJB 3.0 對元數據標記的依賴性很強。在 JSR 175 下元數據標記得以標準化 , 且將包含在 J2SE 5.0 中。標注是一種面向屬性的編程,與Xdoclet類似。不過 , 與需要預編譯的 XDoclet 不同 ,標注是在 編譯時由 Java 編譯器編譯到類中的 ( 取決于如何設置 @Retention ) 。對開發人員而言,標注是類似于public一樣的修飾符,可以在類、字段、方法、參數、本地變量、構造函數、枚舉及包中使用。可以指定可用于生成代碼、歸檔代碼或在運行時提供特殊服務(增強的業務級安全或特定業務邏輯)的屬性,從而在Java代碼中使用標注。J2EE 1.5(5.0)的目標是用標注來簡化開發,因而它會提供自己的一組標注。標注使用@來進行標記,如下所示:

      @Author("Debu Panda")
      @Bean
      public class MySessionBean 
    

      EJB 3.0 的目標是為了簡化開發 , 因而要使用元數據標注來生成若干類似接口一樣的工件 ,要 使用標注而不使用部署描述符。

    使用 POJO 和 POJI

      按照規范化的術語 , JavaBeans 和接口經常分別被稱為 Plain Old Java Objects ( POJO ) 和 Plain Old Java Interfaces ( POJI) 。現在的EJB類和接口將分別類似于POJO和POJI。像home接口之類的不必要工件將不再需要。

      開發人員要么必須在 javax.EJBpackage 中實現一個 EJB 接口 ( SessionBean 、 EntityBean 或 MessageDrivenBean ),要么就是 在 bean 實現類中使用標注。可以使用 Stateless 、 Stateful 、 MessageDriven 或 Entity 標注 bean 類。例如 , 若將一個Stateless EJB 定義為 HelloWorld ,可以這樣 定義該 EJB :

    @Remote
      @Stateless public class HelloWorldBean {
     public String sayHello(String s)
      { System.out.println("Hello: "+s; }
      } 
    

      EJB 的接口可以是遠程的 , 也可以本地接口 ,都 不必實現 EJBObject 或 EJBLocalObject 。必須為 EJB 提供業務接口 , 并在 bean 類中實現該接口 ; 或者在部署期間生成該接口。對于Entity bean,接口是可選的;不過對于 SessionBean 和 MessageDrivenDriven ,接口則是必需的。如果沒有為session bean實現接口,將會生成一個bean接口。生成的接口類型可以是本地的或遠程的,取決于在bean類中使用的標注。從上面的代碼示例可以很清楚地看出, @Remote 是用于為 HelloWorld bean生成遠程接口的。如果需要,可以為EJB同時提供遠程接口和本地接口。

      上面的例子清楚地表明 , 開發人員沒有必要進行大量的尋常任務 , 如定義接口和實現回調方法。

      生成的接口的名稱源自 bean 實現類的名稱。生成的接口對開發人員來說的確不錯。不過,我認為生成接口并沒有多大優勢,因為大多數IDE(如Oracle Jdeveloper)都可動態生成這些接口。

      草案中并沒有清楚地說明什么是 EJB 查找的客戶端要求 ,以及 如何得到調用該 EJB 所需的這些接口。我建議不要使用生成的接口,原因如下:

    • 生成的接口的名稱將從 bean 名稱派生
    • 您可能不愿意在生成的接口中公布 EJB 中 的某些方法 , 而默認情況下 , 生成的接口將公開所有的方法。
    • 您需要客戶端接口來調用 EJB 。

      不再需要回調方法

      EJB2.1 及以前的版本要求為每個 EJB 實現若干個生命周期方法 , 如 ejbPassivate 、 ejbActivate 、 ejbLoad 、 ejbStore 等 , 即使不需要這些方法 , 也要這樣做。例如 , Stateless 會話 bean 不需要 ejbPassivate , 但仍需要在 bean 類 中實現該方法。由于現在的EJB3.0與普通Java類類似,因此實現這些生命周期方法已經不是必需的了。若在EJB中實現回調方法,容器就會調用該方法。

      惟一的例外是 Stateful 會話 bean 中的 ejb Remove 方法 , 在 Stateful 會話 bean 中可以使用 Remove 標注來標注 Stateful 會話 bean 業務方法。如果使用此標注 , 它將會在被標注的方法完成 ( 正常或異常完成 ) 后提示容器刪除 Stateful 會話 bean 實例。例如 , 可以指定以下代碼在執行完 checkOut 方法后刪除 Stateful 會話 bean 實例。

    @Stateful public class Cart {
    ...
    ...
    @Remove public void checkOut() {
    ...
    }
    }
    

      標注與部署描述符對比

      如前所述 , EJB 將不再需要部署描述符 , 而將使用標注。部署描述符中的每個屬性的默認值都將被選定,開發人員無需指定這些屬性,除非要使用默認值以外的值。可以在bean類本身中使用標注來指定這些值。 EJB 3.0 規范為開發人員定義了一組元數據標注 , 如 bean 類型、接口類型、資源引用、事務屬性、安全性等。舉例來說,假設我們希望對某一特定的EJB進行資源引用,則進行如下定義:

    @Resource(name="jdbc/OracleDS", resourceType="javax.sql.DataSource")

      J2EE 供應商 ( 如 Oracle 、 BEA 、IBM ) 將在其特定于供應商的部署描述符中添加屬性標注 , 開發人員將使用這些標注來避免使用部署描述符。對于開發人員而言,這相當有吸引力,因為沒有了他們最討厭的XML描述符。不過,這也帶來一些問題,在使用標記的之前,我們需要多幾分謹慎。

    • 這妨礙了應用程序可移植性目標的實現 , 因為如果 EJB 使用特定于供應商的部署描述符 , 并且不重新編譯 / 重新包裝 EJB ,變化 就不會如愿以償。
    • 無需逐個查看 ejb ,部署描述符就為匯編器 / 部署器 ( ejb-jar ) 提供了 EJB 模塊的完整視圖,它們還按照每一部署的要求調整這些視圖。如果描述符不可用或直到部署結束時才生成,那么后果可能會不堪設想。
    • 各種工具使用部署描述符在 EJB 模塊 中識別 ejb , 當在容器間進行遷移時這會非常有用。
      EJB 3.0 規范還提出了一種重寫部署描述符中標注的方法。不過,規范中并沒有給出重寫標記的具體細節。

      毫無疑問 , 不再使用部署描述符將使新的開發人員能夠更輕松地開展工作 , 但如果使用不當 , 可能會引發管理問題。

    簡化容器管理的持久性

      EJB 3.0 對 CMP 實體 bean 進行了全面的革新 ,以吸引 開發人員的注意力。持久性框架 ( 如 OracleAS TopLink ) 、開放源碼的 Hibernate ) 已成為開發 J2EE 應用程序持久性框架的寵兒,而 實體 bean 由于既 復雜又沉重,已不再受歡迎。 EJB 3.0 采用了一個類似 TopLink 和 Hibernate 的輕量級持久性模型 , 以簡化容器管理的持久性 , 而這對開發人員而言無疑很有誘惑力。我們來簡單了解一下該實體bean計劃,關于持久性改進方面的詳細內容,我們將在另一篇文章中討論。

      實體 bean 正在 作為 POJO 而重獲新生,實體 bean 也 將不再需要組件接口。現在實體bean將被視為純粹的對象,因為它也將支持繼承性和多態性。

      以下是 實體 bean 的源代碼 :

    @Entity public class Employee{
      private Long empNo;
      private String empName;
      private Address address;
      private Hashmap projects = new Hashmap();
      private Double salary;
      @Id(generate=SEQUENCE) public Long getEmpNo() {
      return empNo;
      }
      protected void setEmpNo(Long empNo) {
      this.empNo = empNo;
      }
      public String getEmpName() {
      return EmpName;
      }
      public void setEmpName(String EmpName){
      this.EmpName = EmpName;
      }
      @Dependent public Address getAddress() {
      return address;
      }
      public void setAddress(Address address) {
      this.address = address;
      }
      public Set getProjects() {
      return projects;
      }
      public void setProjects(Set projects) {
      this.projects = projects;
      }
      public Double getSalary() {
      return salary;
      }
      public void setSalary(Double salary) {
      this.salary = salary;
      }
      ....
      }
    

      觀察以上代碼 , 可以發現此 bean 類是當前 實體 bean 的實體類 , 而不是抽象類。

      EJB QL 中對查詢功能進行了若干改進 ,并 在 實體 bean 中支持 SQL 查詢。提出類似于 Hibernate 的新 EntityManager API ( TopLink ' Session API 的一個簡化版本)用于對實體 bean 進行操作 , 即創建、刪除和查找 實體 bean 。。

      我們將在下一篇文章中仔細探討提出的 CMP 實體 bean 的細節。

    簡化 EJB 的客戶端視圖

      使用 EJB ( 即查找和調用)非常復雜 , 即使在應用程序中已經配置了 EJB 。J2EE 1.4和EJB 3.0規范正是要簡化EJB的客戶端視圖。

      若現在就想使用 EJB , 則必須在部署描述符中定義 ejb-ref 或 ejb-local-ref , 查找 EJB 然后再調用。若想調用HelloWorld EJB,以下是在當前實現中調用EJB的最簡單方法。

      首先在部署描述符中定義 EJB 引用 , 如下所示 :

    <ejb-ref>
      <ejb-ref-name>HelloWorldEJB</ejb-ref-name>
      <ejb-ref-type>Session</ejb-ref-type>
      <home>hello.HelloWorldHome</home>
      <remote> hello.HelloWorld</remote>
      </ejb-ref>
    
      然后 , 利用以下代碼查找 EJB 。必須顯式處理 bean 實例的 EJB 查找和創建異常情況。
    try
      {
        Context context = new InitialContext();
    	HelloWorldHome helloHome =
    	  (HelloWorld)PortableRemoteObject.narrow(context.lookup
         ("java:comp/env/ejb/HelloWorldEJB"), HelloWorldHome.class);
    	HelloWorld hello = helloHome.create();
    	  ....
       }
        catch(RemoteException e)
    	{
    	  System.err.println("System/communication error: " + e.getMessage());
    	}
    	catch(NamingException e)
    	{
    	  System.err.println("Communication error: " + e.getMessage());
    	}
    	catch(CreateException e)
    	{
    	  System.err.println("Error creating EJB instance: " + e.getMessage());
    	}
    

      對于 環境變量 , EJB 3.0 建議使用另一種方法,即使用 setter 注入來查找和調用 EJB 。

      以下代碼是使用 setter 注入在另一個 EJB 中查找 HelloWorldEJB 的方法。

    @Inject private void setSessionContext(SessionContext ctx)
      {
      this.ctx = ctx
      }
      ...
      myHello = (HelloWorld)ctx.lookup("java:comp/env/ejb/HelloWorldEJB"); 
    

      仔細研究上面的代碼 , 可以發現 setSessionContext 方法用 @Inject 進行了 標注 , 目的是將依賴注入用于該方法。注入的方法將由容器調用,以在該EJB上調用任一業務方法前設置EJBContext。

      另一個注入 HelloWorld 會話 bean 的直接例子是只使用 @EJBpublic HelloWorld myHello , 這將導致 myHello 通過一個 HelloWorld bean 實例注入。

      可以使用依賴注入來查找任何類型的環境和資源引用 , 如 DataSource 、 JMS 、 Mail 、 Web 服務 等。

    容器外的可測試性和可用性

      當前 EJB 開發人員所關心的一個主要問題不僅包括 EJB 開發的復雜性 , 還包括測試這一難題。開發和測試EJB離不開EJB容器,開發人員也必須熟悉最終的部署平臺,才能進行測試。對于很多企業開發人員而言,這可能不是主要問題。但對于為多個供應商提供支持的ISV而言,這的確是個問題,他們必須維護多個環境以測試其EJB。EJB 3.0規范承諾要提供在容器外進行測試的能力,但目前在規范的草案中并沒有提到細節。

    結束語

      盡管遺漏了很多包裝、組裝以及 API 的細節信息 , EJB 3.0 草案中的提議仍然對企業 Java 開發人員充滿了誘惑。把這些工作留給容器供應商來做,將有助于減少開發人員面對的復雜問題。這就要看容器供應商如何實施這些工作,并使EJB 3.0成為開發企業應用程序的必然之選了。  

    參考資料

    作者簡介

      Debu Panda是 Oracle Application Server 開發團隊的資深產品經理 , 主要致力于 EJB 容器和 Transaction Manager 的開發。他在IT行業的從業經驗超過13年,在很多雜志上都發表過文章,并在許多技術會議上發表演講。欲了解其針對J2EE的weblog,請訪問: http://radio.weblogs.com/0135826/

    from: http://dev2dev.bea.com.cn/techdoc/2005070105.html

    posted on 2005-12-18 21:33 weidagang2046 閱讀(154) 評論(0)  編輯  收藏 所屬分類: Java

    主站蜘蛛池模板: 8x8×在线永久免费视频| 国产成人精品123区免费视频| 亚洲日本国产乱码va在线观看| 久久久久免费看黄A片APP| 特色特黄a毛片高清免费观看| 亚洲av成人无码久久精品| 无码人妻一区二区三区免费手机| 无码的免费不卡毛片视频| 亚洲无成人网77777| 亚洲女同成人AⅤ人片在线观看| 99视频在线免费看| 欧洲美女大片免费播放器视频| 久久久久亚洲av无码专区喷水| 国产一区二区三区在线免费| 国产精品99久久免费观看 | 羞羞视频在线观看免费| 4480yy私人影院亚洲| 免费一级特黄特色大片在线观看| 最近高清中文字幕免费| sss在线观看免费高清| 在线亚洲午夜片AV大片| 久久精品国产亚洲AV果冻传媒| 免费国产a国产片高清网站| 免费A级毛片无码视频| 国产精品九九久久免费视频| 亚洲人成未满十八禁网站| 亚洲视频在线观看| 狠狠色婷婷狠狠狠亚洲综合 | 在线看片无码永久免费aⅴ| 亚洲视频免费在线观看| 草久免费在线观看网站| 亚洲av成人一区二区三区在线播放 | a级毛片免费观看视频| 久久亚洲精品无码网站| 亚洲一区电影在线观看| 亚洲国产精品人久久| 亚洲人成影院在线无码按摩店| 日韩亚洲精品福利| 国产精品四虎在线观看免费| 中文字幕av无码无卡免费| 久久国产乱子伦免费精品|