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

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

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

    weidagang2046的專(zhuān)欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評(píng)論 - 101, 引用 - 0
    數(shù)據(jù)加載中……

    用 EJB3.0 簡(jiǎn)化 EJB 開(kāi)發(fā)

    討論

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

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

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

    EJB 模型的復(fù)雜性

      在開(kāi)始討論EJB 3.0帶來(lái)的新特性之前,讓我們了解一下當(dāng)前 EJB 模型的復(fù)雜性。

    • 當(dāng)前的 EJB 模型 需要?jiǎng)?chuàng)建若干個(gè)組件接口并實(shí)現(xiàn)若干個(gè)不必要的回調(diào)方法。
    • 這些組件接口需要實(shí)現(xiàn) EJB Object 或 EJB LocalObject , 且需要處理許多不必要的異常情況。
    • EJB 部署描述符復(fù)雜 , 且易出錯(cuò)。
    • 容器管理的持久性基于 EJB 模型 , 也十分復(fù)雜 , 不利于開(kāi)發(fā)和管理。缺乏一些基本功能(如按標(biāo)準(zhǔn)方法使用數(shù)據(jù)庫(kù)序列定義主鍵等),且 EJBQL 十分受限。
    • 由于有繼承性和多態(tài)性方面的約束 , EJB 組件與其源對(duì)象并不相同。
    • EJB 的主要缺點(diǎn)之一就是不能在 EJB 容器外測(cè)試 EJB 模塊 ,而且 對(duì)開(kāi)發(fā)人員而言 , 要在容器內(nèi)調(diào)試 EJB 是件可怕的事。
    • 如果用過(guò) EJB , 您就會(huì)知道查找和調(diào)用 EJB 的有多復(fù)雜了。為了在應(yīng)用程序中使用 EJB ,您必須了解 JNDI 的每個(gè)細(xì)節(jié)。

    簡(jiǎn)化開(kāi)發(fā)人員視圖

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

      EJB 3.0希望使用以下方法來(lái)克服這種復(fù)雜性:

    • 無(wú)需使用接口和部署描述符 , 而是由容器使用元數(shù)據(jù)標(biāo)注生成。
    • 將 普通 Java 類(lèi)用作 EJB ,將 普通業(yè)務(wù)接口用于EJB。

    元數(shù)據(jù)標(biāo)注

      EJB 3.0 對(duì)元數(shù)據(jù)標(biāo)記的依賴(lài)性很強(qiáng)。在 JSR 175 下元數(shù)據(jù)標(biāo)記得以標(biāo)準(zhǔn)化 , 且將包含在 J2SE 5.0 中。標(biāo)注是一種面向?qū)傩缘木幊蹋cXdoclet類(lèi)似。不過(guò) , 與需要預(yù)編譯的 XDoclet 不同 ,標(biāo)注是在 編譯時(shí)由 Java 編譯器編譯到類(lèi)中的 ( 取決于如何設(shè)置 @Retention ) 。對(duì)開(kāi)發(fā)人員而言,標(biāo)注是類(lèi)似于public一樣的修飾符,可以在類(lèi)、字段、方法、參數(shù)、本地變量、構(gòu)造函數(shù)、枚舉及包中使用。可以指定可用于生成代碼、歸檔代碼或在運(yùn)行時(shí)提供特殊服務(wù)(增強(qiáng)的業(yè)務(wù)級(jí)安全或特定業(yè)務(wù)邏輯)的屬性,從而在Java代碼中使用標(biāo)注。J2EE 1.5(5.0)的目標(biāo)是用標(biāo)注來(lái)簡(jiǎn)化開(kāi)發(fā),因而它會(huì)提供自己的一組標(biāo)注。標(biāo)注使用@來(lái)進(jìn)行標(biāo)記,如下所示:

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

      EJB 3.0 的目標(biāo)是為了簡(jiǎn)化開(kāi)發(fā) , 因而要使用元數(shù)據(jù)標(biāo)注來(lái)生成若干類(lèi)似接口一樣的工件 ,要 使用標(biāo)注而不使用部署描述符。

    使用 POJO 和 POJI

      按照規(guī)范化的術(shù)語(yǔ) , JavaBeans 和接口經(jīng)常分別被稱(chēng)為 Plain Old Java Objects ( POJO ) 和 Plain Old Java Interfaces ( POJI) 。現(xiàn)在的EJB類(lèi)和接口將分別類(lèi)似于POJO和POJI。像home接口之類(lèi)的不必要工件將不再需要。

      開(kāi)發(fā)人員要么必須在 javax.EJBpackage 中實(shí)現(xiàn)一個(gè) EJB 接口 ( SessionBean 、 EntityBean 或 MessageDrivenBean ),要么就是 在 bean 實(shí)現(xiàn)類(lèi)中使用標(biāo)注。可以使用 Stateless 、 Stateful 、 MessageDriven 或 Entity 標(biāo)注 bean 類(lèi)。例如 , 若將一個(gè)Stateless EJB 定義為 HelloWorld ,可以這樣 定義該 EJB :

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

      EJB 的接口可以是遠(yuǎn)程的 , 也可以本地接口 ,都 不必實(shí)現(xiàn) EJBObject 或 EJBLocalObject 。必須為 EJB 提供業(yè)務(wù)接口 , 并在 bean 類(lèi)中實(shí)現(xiàn)該接口 ; 或者在部署期間生成該接口。對(duì)于Entity bean,接口是可選的;不過(guò)對(duì)于 SessionBean 和 MessageDrivenDriven ,接口則是必需的。如果沒(méi)有為session bean實(shí)現(xiàn)接口,將會(huì)生成一個(gè)bean接口。生成的接口類(lèi)型可以是本地的或遠(yuǎn)程的,取決于在bean類(lèi)中使用的標(biāo)注。從上面的代碼示例可以很清楚地看出, @Remote 是用于為 HelloWorld bean生成遠(yuǎn)程接口的。如果需要,可以為EJB同時(shí)提供遠(yuǎn)程接口和本地接口。

      上面的例子清楚地表明 , 開(kāi)發(fā)人員沒(méi)有必要進(jìn)行大量的尋常任務(wù) , 如定義接口和實(shí)現(xiàn)回調(diào)方法。

      生成的接口的名稱(chēng)源自 bean 實(shí)現(xiàn)類(lèi)的名稱(chēng)。生成的接口對(duì)開(kāi)發(fā)人員來(lái)說(shuō)的確不錯(cuò)。不過(guò),我認(rèn)為生成接口并沒(méi)有多大優(yōu)勢(shì),因?yàn)榇蠖鄶?shù)IDE(如Oracle Jdeveloper)都可動(dòng)態(tài)生成這些接口。

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

    • 生成的接口的名稱(chēng)將從 bean 名稱(chēng)派生
    • 您可能不愿意在生成的接口中公布 EJB 中 的某些方法 , 而默認(rèn)情況下 , 生成的接口將公開(kāi)所有的方法。
    • 您需要客戶(hù)端接口來(lái)調(diào)用 EJB 。

      不再需要回調(diào)方法

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

      惟一的例外是 Stateful 會(huì)話(huà) bean 中的 ejb Remove 方法 , 在 Stateful 會(huì)話(huà) bean 中可以使用 Remove 標(biāo)注來(lái)標(biāo)注 Stateful 會(huì)話(huà) bean 業(yè)務(wù)方法。如果使用此標(biāo)注 , 它將會(huì)在被標(biāo)注的方法完成 ( 正常或異常完成 ) 后提示容器刪除 Stateful 會(huì)話(huà) bean 實(shí)例。例如 , 可以指定以下代碼在執(zhí)行完 checkOut 方法后刪除 Stateful 會(huì)話(huà) bean 實(shí)例。

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

      標(biāo)注與部署描述符對(duì)比

      如前所述 , EJB 將不再需要部署描述符 , 而將使用標(biāo)注。部署描述符中的每個(gè)屬性的默認(rèn)值都將被選定,開(kāi)發(fā)人員無(wú)需指定這些屬性,除非要使用默認(rèn)值以外的值。可以在bean類(lèi)本身中使用標(biāo)注來(lái)指定這些值。 EJB 3.0 規(guī)范為開(kāi)發(fā)人員定義了一組元數(shù)據(jù)標(biāo)注 , 如 bean 類(lèi)型、接口類(lèi)型、資源引用、事務(wù)屬性、安全性等。舉例來(lái)說(shuō),假設(shè)我們希望對(duì)某一特定的EJB進(jìn)行資源引用,則進(jìn)行如下定義:

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

      J2EE 供應(yīng)商 ( 如 Oracle 、 BEA 、IBM ) 將在其特定于供應(yīng)商的部署描述符中添加屬性標(biāo)注 , 開(kāi)發(fā)人員將使用這些標(biāo)注來(lái)避免使用部署描述符。對(duì)于開(kāi)發(fā)人員而言,這相當(dāng)有吸引力,因?yàn)闆](méi)有了他們最討厭的XML描述符。不過(guò),這也帶來(lái)一些問(wèn)題,在使用標(biāo)記的之前,我們需要多幾分謹(jǐn)慎。

    • 這妨礙了應(yīng)用程序可移植性目標(biāo)的實(shí)現(xiàn) , 因?yàn)槿绻?EJB 使用特定于供應(yīng)商的部署描述符 , 并且不重新編譯 / 重新包裝 EJB ,變化 就不會(huì)如愿以?xún)敗?
    • 無(wú)需逐個(gè)查看 ejb ,部署描述符就為匯編器 / 部署器 ( ejb-jar ) 提供了 EJB 模塊的完整視圖,它們還按照每一部署的要求調(diào)整這些視圖。如果描述符不可用或直到部署結(jié)束時(shí)才生成,那么后果可能會(huì)不堪設(shè)想。
    • 各種工具使用部署描述符在 EJB 模塊 中識(shí)別 ejb , 當(dāng)在容器間進(jìn)行遷移時(shí)這會(huì)非常有用。
      EJB 3.0 規(guī)范還提出了一種重寫(xiě)部署描述符中標(biāo)注的方法。不過(guò),規(guī)范中并沒(méi)有給出重寫(xiě)標(biāo)記的具體細(xì)節(jié)。

      毫無(wú)疑問(wèn) , 不再使用部署描述符將使新的開(kāi)發(fā)人員能夠更輕松地開(kāi)展工作 , 但如果使用不當(dāng) , 可能會(huì)引發(fā)管理問(wèn)題。

    簡(jiǎn)化容器管理的持久性

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

      實(shí)體 bean 正在 作為 POJO 而重獲新生,實(shí)體 bean 也 將不再需要組件接口。現(xiàn)在實(shí)體bean將被視為純粹的對(duì)象,因?yàn)樗矊⒅С掷^承性和多態(tài)性。

      以下是 實(shí)體 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;
      }
      ....
      }
    

      觀察以上代碼 , 可以發(fā)現(xiàn)此 bean 類(lèi)是當(dāng)前 實(shí)體 bean 的實(shí)體類(lèi) , 而不是抽象類(lèi)。

      EJB QL 中對(duì)查詢(xún)功能進(jìn)行了若干改進(jìn) ,并 在 實(shí)體 bean 中支持 SQL 查詢(xún)。提出類(lèi)似于 Hibernate 的新 EntityManager API ( TopLink ' Session API 的一個(gè)簡(jiǎn)化版本)用于對(duì)實(shí)體 bean 進(jìn)行操作 , 即創(chuàng)建、刪除和查找 實(shí)體 bean 。。

      我們將在下一篇文章中仔細(xì)探討提出的 CMP 實(shí)體 bean 的細(xì)節(jié)。

    簡(jiǎn)化 EJB 的客戶(hù)端視圖

      使用 EJB ( 即查找和調(diào)用)非常復(fù)雜 , 即使在應(yīng)用程序中已經(jīng)配置了 EJB 。J2EE 1.4和EJB 3.0規(guī)范正是要簡(jiǎn)化EJB的客戶(hù)端視圖。

      若現(xiàn)在就想使用 EJB , 則必須在部署描述符中定義 ejb-ref 或 ejb-local-ref , 查找 EJB 然后再調(diào)用。若想調(diào)用HelloWorld EJB,以下是在當(dāng)前實(shí)現(xiàn)中調(diào)用EJB的最簡(jiǎn)單方法。

      首先在部署描述符中定義 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 實(shí)例的 EJB 查找和創(chuàng)建異常情況。
    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());
    	}
    

      對(duì)于 環(huán)境變量 , EJB 3.0 建議使用另一種方法,即使用 setter 注入來(lái)查找和調(diào)用 EJB 。

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

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

      仔細(xì)研究上面的代碼 , 可以發(fā)現(xiàn) setSessionContext 方法用 @Inject 進(jìn)行了 標(biāo)注 , 目的是將依賴(lài)注入用于該方法。注入的方法將由容器調(diào)用,以在該EJB上調(diào)用任一業(yè)務(wù)方法前設(shè)置EJBContext。

      另一個(gè)注入 HelloWorld 會(huì)話(huà) bean 的直接例子是只使用 @EJBpublic HelloWorld myHello , 這將導(dǎo)致 myHello 通過(guò)一個(gè) HelloWorld bean 實(shí)例注入。

      可以使用依賴(lài)注入來(lái)查找任何類(lèi)型的環(huán)境和資源引用 , 如 DataSource 、 JMS 、 Mail 、 Web 服務(wù) 等。

    容器外的可測(cè)試性和可用性

      當(dāng)前 EJB 開(kāi)發(fā)人員所關(guān)心的一個(gè)主要問(wèn)題不僅包括 EJB 開(kāi)發(fā)的復(fù)雜性 , 還包括測(cè)試這一難題。開(kāi)發(fā)和測(cè)試EJB離不開(kāi)EJB容器,開(kāi)發(fā)人員也必須熟悉最終的部署平臺(tái),才能進(jìn)行測(cè)試。對(duì)于很多企業(yè)開(kāi)發(fā)人員而言,這可能不是主要問(wèn)題。但對(duì)于為多個(gè)供應(yīng)商提供支持的ISV而言,這的確是個(gè)問(wèn)題,他們必須維護(hù)多個(gè)環(huán)境以測(cè)試其EJB。EJB 3.0規(guī)范承諾要提供在容器外進(jìn)行測(cè)試的能力,但目前在規(guī)范的草案中并沒(méi)有提到細(xì)節(jié)。

    結(jié)束語(yǔ)

      盡管遺漏了很多包裝、組裝以及 API 的細(xì)節(jié)信息 , EJB 3.0 草案中的提議仍然對(duì)企業(yè) Java 開(kāi)發(fā)人員充滿(mǎn)了誘惑。把這些工作留給容器供應(yīng)商來(lái)做,將有助于減少開(kāi)發(fā)人員面對(duì)的復(fù)雜問(wèn)題。這就要看容器供應(yīng)商如何實(shí)施這些工作,并使EJB 3.0成為開(kāi)發(fā)企業(yè)應(yīng)用程序的必然之選了。  

    參考資料

    作者簡(jiǎn)介

      Debu Panda是 Oracle Application Server 開(kāi)發(fā)團(tuán)隊(duì)的資深產(chǎn)品經(jīng)理 , 主要致力于 EJB 容器和 Transaction Manager 的開(kāi)發(fā)。他在IT行業(yè)的從業(yè)經(jīng)驗(yàn)超過(guò)13年,在很多雜志上都發(fā)表過(guò)文章,并在許多技術(shù)會(huì)議上發(fā)表演講。欲了解其針對(duì)J2EE的weblog,請(qǐng)?jiān)L問(wèn): http://radio.weblogs.com/0135826/

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

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

    主站蜘蛛池模板: 亚洲午夜电影一区二区三区| 91在线手机精品免费观看| 亚洲精品第一国产综合精品| 亚洲色偷偷狠狠综合网| 最近的免费中文字幕视频| 2019中文字幕在线电影免费| 99在线免费视频| 男人和女人高潮免费网站| 亚洲中文字幕久久精品无码A| 亚洲日本va午夜中文字幕一区| 相泽亚洲一区中文字幕| 国产无遮挡吃胸膜奶免费看视频| 91免费播放人人爽人人快乐| a级大片免费观看| www.av在线免费观看| 真正全免费视频a毛片| 亚洲性色AV日韩在线观看| 亚洲国产成人精品无码一区二区| 久久91亚洲人成电影网站| 亚洲精品国产高清不卡在线| 日本媚薬痉挛在线观看免费| 成年女人18级毛片毛片免费观看| 67194成手机免费观看| 最近中文字幕高清免费中文字幕mv| 国产精品九九久久免费视频 | 成全动漫视频在线观看免费高清版下载| 亚洲AV无码一区二区三区久久精品| 亚洲一级毛片中文字幕| 亚洲最大黄色网站| 亚洲精品一区二区三区四区乱码| 亚洲福利视频一区| 亚洲国产精品国自产电影| 亚洲va久久久噜噜噜久久狠狠 | AAAAA级少妇高潮大片免费看| 免费国产va视频永久在线观看| 老司机午夜精品视频在线观看免费| 看亚洲a级一级毛片| 午夜亚洲乱码伦小说区69堂| 野花视频在线官网免费1| 免费看一级一级人妻片| 人成午夜免费大片在线观看|