Sung in Blog

                     一些技術(shù)文章 & 一些生活雜碎
          實現(xiàn)EJB

          如果你選擇使用EJB,Spring能在EJB實現(xiàn)和客戶端訪問EJB兩方面都提供很大的好處。

          對業(yè)務(wù)邏輯進行重構(gòu),把它從EJB facades中取出到POJO已經(jīng)得到了廣泛的認同。(不講別的,這使得業(yè)務(wù)邏輯更容易單元測試,因為EJB嚴重依賴于容器而難于分離測試。)Spring為session bean和message driver bean提供了方便的超類,使得通過自動載入基于包含在EJB Jar文件中的XML文檔BeanFactory讓這變得很容易。

          這意味著stateless session EJB可以這么獲得和使用所需對象:

          代碼:

          import org.springframework.ejb.support.AbstractStatelessSessionBean;

          public class MyEJB extends AbstractStatelessSessionBean
                   implements MyBusinessInterface {
             private MyPOJO myPOJO;

             protected void onEjbCreate() {
                this.myPOJO = getBeanFactory().getBean("myPOJO");
             }

             public void myBusinessMethod() {
                this.myPOJO.invokeMethod();
             }
          }

          假定MyPOJO是一個接口,它的實現(xiàn)類——以及任何它需要的配置,注入基本的屬性和更多的合作者——在XML bean factory 定義中隱藏。

          我們通過在ejb-jar.xmldeployment descriptor中名為ejb/BeanFactoryPath的環(huán)境變量定義告訴Spring去哪兒裝載XML文檔。如下:

          代碼:

          <session>
             <ejb-name>myComponent</ejb-name>
             <local-home>com.test.ejb.myEjbBeanLocalHome</local-home>
             <local>com.mycom.MyComponentLocal</local>
             <ejb-class>com.mycom.MyComponentEJB</ejb-class>
             <session-type>Stateless</session-type>
             <transaction-type>Container</transaction-type>

             <env-entry>
                <env-entry-name>ejb/BeanFactoryPath</env-entry-name>
                <env-entry-type>java.lang.String</env-entry-type>
                <env-entry-value>/myComponent-ejb-beans.xml</env-entry-value></env-entry>
             </env-entry>
          </session>

          myComponent-ejb-beans.xml 文件將會從classpath裝載:在本例中,是EJB Jar文件的根目錄。每個EJB都能指定自己的XML文檔,因而這個機制能在每個EJB Jar文件中使用多次。

          Spring 的超類實現(xiàn)了EJB中諸如setSessionContext()和ejbCreate()的生命周期管理的方法,讓應(yīng)用程序開發(fā)者只需選擇是否實現(xiàn)Spring的onEjbCreate()方法。
           
           
          使用EJB

          Spring還讓實現(xiàn)EJB變得更加容易。許多EJB程序使用Service Locator和Business Delegate模式。這些比在客戶代碼中遍布JNDI查找強多了,但是它們常見的實現(xiàn)方式有顯著的缺點,例如:


            使用EJB的典型代碼依賴Service Locator或者Business Delegate singletons,使得測試難于進行。

            在Service Locator模式?jīng)]有使用Business Delegate的情況下,程序代碼還要在EJB home中調(diào)用create()方法,并且處理可能導(dǎo)致的異常。因而仍然綁定在EJB API身上,忍受著EJB 編程模型的復(fù)雜度。

            實現(xiàn)Business Delegate模式通常導(dǎo)致顯著的代碼重復(fù),其中我們必須編寫大量僅僅是調(diào)用EJB同等方法的方法。

          基于這些和其他原因,傳統(tǒng)的EJB訪問,如在Sun Adventure Builder和OTN J2EE Virtual Shopping Mall中展示的那樣,會降低生產(chǎn)率并且?guī)盹@著的復(fù)雜度。

          Spring通過引入codeless business delegate前進了一步。有了Spring,你不再需要再編寫另一個Service Locator,另一個JNDI查找,或者在硬編碼的Business Delegate中重復(fù)代碼,除非你肯定這增加了價值。

          例如,假定我們有使用local EJB的web controller。我們將遵循最佳實踐,使用EJB Business Methods Interface模式,EJB的local interface extend非EJB專有的業(yè)務(wù)方法接口。(這么做的主要的一個原因是確保在本地接口和bean實現(xiàn)類中方法簽名的自動同步。)讓我們調(diào)用這個業(yè)務(wù)方法接口MyComponent。當(dāng)然我們還需要實現(xiàn)local home接口并且提供實現(xiàn)SessionBean和MyComponent業(yè)務(wù)方法的bean的實現(xiàn)類。

          用了Spring EJB 訪問,我們把我們的web層controller和EJB實現(xiàn)掛接上所需要進行的Java編碼僅僅是在我們的controller中暴露一個類型MyComponent的setter方法。這將如下保存作為實例變量的引用:

          代碼:

          private MyComponent myComponent;

          public void setMyComponent(MyComponent myComponent) {
             this.myComponent = myComponent;
          }

          我們隨后在任何業(yè)務(wù)方法中使用這個實例變量。

          Spring自動完稱剩下的工作,通過像這樣的XML bean定義。LocalStatelessSessionProxyFactoryBean是一個可以用于任何EJB的通用factory bean。它創(chuàng)建的對象能夠自動被Spring轉(zhuǎn)型為MyComponent類型。

          代碼:

          <bean id="myComponent"
          class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">

             <property name="jndiName"><value>myComponent</value></property>
             <property name="businessInterface"><value>com.mycom.MyComponent</value></property>
          </bean>

          <bean id="myController"
             class = "com.mycom.myController"
          >
             <property name="myComponent"><ref bean="myComponent"/></property>
          </bean>

          在幕后有許多魔法般的事情發(fā)生,Spring AOP framework的殷勤,雖然不強迫你使用AOP的概念享受這些結(jié)果。“myComponent”bean定義為EJB創(chuàng)建一個代理,它實現(xiàn)了業(yè)務(wù)方法的接口。EJB local home在啟動的時候被緩存,因而只需要一次JNDI查找。每次EJB被調(diào)用的時候,代理調(diào)用local EJB中的create()方法并且調(diào)用EJB中對應(yīng)的業(yè)務(wù)方法。

          myController bean定義為這個代理設(shè)置controller類的myController屬性。

          這個EJB訪問機制極大簡化了應(yīng)用程序的代碼:


            Web層的代碼不依賴于EJB的使用。如果你想要使用POJO,mock object或者其他test stub替代EJB引用,我們可以簡單地改動一下myComponent bean定義而不影響一行Java代碼

            我們還不需要寫一行JNDI查找或者其他EJB plumbing code。

          在實際程序中的性能測試和經(jīng)驗標(biāo)明這種方法(包括對目標(biāo)EJB的反射調(diào)用)的性能影響是很小的,在典型的應(yīng)用中檢測不出。記住無論如何我們都不希望使用fine-grained的EJB調(diào)用,因為會有有關(guān)應(yīng)用服務(wù)器上的EJB的底層架構(gòu)方面的代價。

          我們可以把相同方法應(yīng)用于遠程EJB,通過類似org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean factory bean的方法。然而我們無法隱藏遠程EJB的業(yè)務(wù)方法接口中的RemoteException。
          posted on 2005-10-26 16:08 Sung 閱讀(269) 評論(0)  編輯  收藏 所屬分類: Java
          主站蜘蛛池模板: 威宁| 文昌市| 临颍县| 郎溪县| 龙岩市| 郓城县| 西林县| 兴宁市| 上思县| 高州市| 义乌市| 临安市| 桃园市| 广元市| 武平县| 辽中县| 汾西县| 临武县| 依安县| 景宁| 罗源县| 康保县| 苍梧县| 深泽县| 平昌县| 玉屏| 建湖县| 梁平县| 汾西县| 嘉善县| 凤冈县| 张家港市| 浠水县| 民乐县| 偏关县| 盖州市| 时尚| 新竹县| 合川市| 江孜县| 巴东县|