亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

JavaEJB容器的存取和實現

2019-11-18 13:48:27
字體:
來源:轉載
供稿:網友

  作為輕量級的容器,SPRing經常被認為是EJB的替代品。我們也相信,對于很多 (不一定是絕大多數)應用和用例,相對于通過EJB容器來實現相同的功能而言, Sping作為容器,加上它在事務,ORM和JDBC存取這些領域中豐富的功能支持, Spring的確是更好的選擇。
  
  不過,需要非凡注重的是,使用了Spring并不是說我們就不能用EJB了, 實際上,Spring大大簡化了從中訪問和實現EJB組件或只實現(EJB組件)其功能的復雜性。 另外,假如通過Spring來訪問EJB組件服務,以后就可以在本地EJB組件,遠程EJB組件, 或者是POJO(簡單java對象)這些變體之間透明地切換服務的實現,而不需要修改 客戶端的代碼。
  
  本章,我們來看看Spring是如何幫助我們訪問和實現EJB組件的。尤其是在訪問 無狀態session Bean(SLSBs)的時候,Spring非凡有用,現在我們就由此開始討論。
  
  訪問EJB 1.1. 概念要調用本地或遠程無狀態Session Bean上的方法,通??蛻舳说拇a必須 進行JNDI查找,得到(本地或遠程的)EJB Home對象,然后調用該對象的"create" 方法,才能得到實際的(本地或遠程的)EJB對象。前后調用了不止一個EJB組件 上的方法。
  
  為了避免重復的底層調用,很多EJB應用使用了服務定位器(Service Locator) 和業務委托(Bussiness Delegate)模式,這樣要比在客戶端代碼中到處進行JNDI 查找更好些,不過它們的常見的實現都有明顯的缺陷。例如:
  
  通常,若是依靠于服務定位器或業務代理單件來使用EJB,則很難對代碼進 行測試。
  
  在僅使用了服務定位器模式而不使用業務委托模式的情況下,應用程序 代碼仍然需要調用EJB Home組件的create方法,還是要處理由此引入的異常。 導致代碼仍然保留了與EJB API的耦合性以及EJB編程模型的復雜性。
  
  實現業務委托模式通常會導致大量的冗余代碼,因為我們不得不編寫 很多方法,而它們所做的僅僅是調用EJB組件的同名方法。
  
  Spring采用的方法是答應創建并使用代理對象,一般是在Spring的 applicationContext或BeanFactory里面進行配置,這樣就和業務代理類似,只需要 少量的代碼。我們不再需要另外編寫額外的服務定位器或JNDI查找的代碼,或者是手寫 的業務委托對象里面冗余的方法,除非它們可以帶來實質性的好處。
  
  1.2. 訪問本地的無狀態Session Bean(SLSB)
  假設有一個web控制器需要使用本地EJB組件。我們遵循前人的實踐經驗, 于是使用了EJB的業務方法接口(Business Methods Interface)模式,這樣, 這個EJB組件的本地接口就擴展了非EJB特定的業務方法接口。讓我們假定這個 業務方法接口叫MyComponent.
  
  public interface MyComponent {……
  }(使用業務方法接口模式的一個主要原因就是為了保證本地接口和bean的實現類 之間方法簽名的同步是自動的。另外一個原因是它使得稍后我們改用基于POJO(簡單Java對象) 的服務實現更加輕易,只要這樣的改變是有利的。當然,我們也需要實現 本地Home接口,并提供一個Bean實現類,使其實現接口SessionBean和業務方法接口 MyComponent.現在為了把我們Web層的控制器和EJB的實現鏈接起來,我們唯一要寫 的Java代碼就是在控制器上公布一個形參為MyComponent的setter方法。這樣就可以 把這個引用保存在控制器的一個實例變量中。
  
  private MyComponent myComponent;

public void setMyComponent(MyComponent myComponent) {
    this.myComponent = myComponent;
}
  然后我們可以在控制器的任意業務方法里面使用這個實例變量。假設我們現在 從Spring的ApplicationContext或BeanFactory獲得該控制器對象,我們就可以在 同一個上下文中配置一個LocalStatelessSessionProxyFactoryBean 的實例,它將作為EJB組件的代理對象。這個代理對象的配置和控制器的屬性 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>
  這些看似簡單的代碼背后隱藏了很多復雜的處理,比如默默工作的Spring AOP框架,我們甚至不必知道這些概念,一樣可以享用它的結果。Bean myComponent 的定義中創建了一個該EJB組件的代理對象,它實現了業務方法接口。這個EJB組件的 本地Home對象在啟動的時候就被放到了緩存中,所以只需要執行一次JNDI查找即可。 每當EJB組件被調用的時候,這個代理對象就調用本地EJB組件的create方法,并調用 該EJB組件的相應的業務方法。
  
  在Bean myController的定義中,控制器類的屬性 myController的值被設置為上面代理對象。
  
  這樣的EJB組件訪問方式大大簡化了應用程序代碼:Web層(或其他EJB客戶端) 的代碼不再依靠于EJB組件的使用。假如我們想把這個EJB的引用替換為一個POJO, 或者是模擬用的對象或其他測試組件,我們只需要簡單地修改Bean myComponent 的定義中僅僅一行Java代碼,此外,我們也不再需要在應用程序中編寫任何JNDI查找 或其它EJB相關的代碼。
  
  評測和實際應用中的經驗表明,這種方式的性能負荷極小,(盡管其中 使用了反射方式以調用目標EJB組件的方法),通常的使用中我們幾乎覺察不出。請記住 我們并不想頻繁地調用EJB組件的底層方法,雖然如此,有些性能代價是與應用服務器 中EJB的基礎框架相關的。
  
  關于JNDI查找有一點需要注重。在Bean容器中,這個類通常最好用作單件 (沒理由使之成為原型)。不過,假如這個Bean容器會預先實例化單件(類似xml ApplicationContext的變體的行為),假如在EJB容器載入目標EJB前載入bean容器, 我們就可能會碰到問題。因為JNDI查找會在該類的init方法中被執行并且緩存結果, 這樣就導致該EJB不能被綁定到目標位置。解決方案就是不要預先實例化這個工廠對象, 而答應它在第一次用到的時候再創建,在XML容器中,這是通過屬性 lazy-init來控制的。
  
  盡管大部分Spring的用戶不會對這些感愛好,但那些對EJB進行AOP的具體應用 的用戶則會想看看LocalSlsbInvokerInterceptor.
  
  1.3. 訪問遠程的無狀態Session Bean(SLSB)
  基本上訪問遠程EJB與訪問本地EJB差別不大,除了前者使用的是 SimpleRemoteStatelessSessionProxyFactoryBean.當然, 無論是否使用Spring,遠程調用的語義都相同,不過,對于使用的場景和錯誤處理 來說,調用另外一臺計算機上不同虛擬機中的對象的方法其處理有所不同。
  
  與不使用Spring方式的EJB客戶端相比,Spring的EJB客戶端有一個額外的 好處。通常假如客戶端代碼隨意在本地EJB和遠程EJB的調用之間往返切換,就有 一個問題。這是因為遠程接口的方法需要聲明其會拋出RemoteException ,然后客戶端代碼必須處理這種異常,但是本地接口的方法卻不需要這樣。 假如要把針對本地EJB的代碼改為訪問遠程EJB,就需要修改客戶端代碼,增加 對RemoteException的處理,反之就需要去掉這樣的 異常處理。使用Spring 的遠程EJB代理,我們就不再需要在業務方法接口和EJB的 代碼實現中聲明會拋出RemoteException,而是定義一個 相似的遠程接口,唯一不同就是它拋出的是RemoteAccessException, 然后交給代理對象去動態的協調這兩個接口。也就是說,客戶端代碼不再需要與 RemoteException這個顯式(checked)異常打交道,實際運行中 所有拋出的異常RemoteException都會被捕捉并轉換成一個 隱式(non-checked)的RemoteAccessException,它是 RuntimeException的一個子類。這樣目標服務端就可以 在本地EJB或遠程EJB(甚至POJO)之間隨意地切換,客戶端不再需要關心甚至 根本不會覺察到這種切換。當然,這些都是可選的,我們并不阻止在業務接口中聲明 異常RemoteExceptions.
  
  2. 使用Spring提供的輔助類實現EJB組件Spring也提供了一些輔助類來為EJB組件的實現提供便利。它們是為了倡導一些 好的實踐經驗,比如把業務邏輯放在在EJB層之后的POJO中實現,只把事務隔離和 遠程調用這些職責留給EJB.
  
  要實現一個無狀態或有狀態的Session Bean,或消息驅動Bean,我們的實現 可以繼續分別繼續AbstractStatelessSessionBean, AbstractStatefulSessionBean,和 AbstractMessageDrivenBean/AbstractJmsMessageDrivenBean
  
  考慮這個例子:我們把無狀態Session Bean的實現委托給普通的Java服務對象。 業務接口的定義如下:
  
public interface MyComponent {
    public void myMethod(...);
    ...
}
  這是簡單Java對象實現方式的類:

public class MyComponentImpl implements MyComponent {
    public String myMethod(...) {
        ...
    }
    ...
}
  最后是無狀態Session Bean自身:

public class MyComponentEJB implements extends AbstractStatelessSessionBean
        implements MyComponent {

    MyComponent _myComp;

    /**
     * OBTain our POJO service object from the BeanFactory/ApplicationContext
     * @see org.springframework.ejb.support.AbstractStatelessSessionBean#onEjbCreate()
     */
    protected void onEjbCreate() throws CreateException {
        _myComp = (MyComponent) getBeanFactory().getBean(
            ServicesConstants.CONTEXT_MYCOMP_ID);
    }

    // for business method, delegate to POJO service impl.
    public String myMethod(...) {
        return _myComp.myMethod(...);
    }
    ...
}
  Spring為支持EJB而提供的這些基類默認情況下會創建并載入一個BeanFactory (這個例子里,它是ApplicationContext的子類),作為其生命周期的一部分, 供EJB使用(比如像上面的代碼那樣用來獲取POJO服務對象)。載入的工作是通過 一個策略對象完成的,它是BeanFactoryLocator的子類。 默認情況下,實際使用的BeanFactoryLocator的實現類是 ContextJndiBeanFactoryLocator,它根據一個JNDI環境變量 來創建一個ApplicationContext對象(這里是EJB類,路徑是 java:comp/env/ejb/BeanFactoryPath)。假如需要改變 BeanFactory或ApplicationContext的載入策略,我們可以在子類中重定義了的 setSessionContext()方法或具體EJB子類的構造函數中調用 setBeanFactoryLocator()方法來改變默認使用的 BeanFactoryLocator實現類。具體細節請參考JavaDoc.
  
  如JavaDoc中所述,有狀態Session Bean在其生命周期中可能會被鈍化并重新激活, 假如是不可序列化的BeanFactory或ApplicationContext,由于它們不會被EJB容器保存, 所以還需要手動在ejbPassivate和ejbActivate 這兩個方法中分別調用unloadBeanFactory()和loadBeanFactory, 才能在鈍化或激活的時候卸載或載入。
  
  有些情況下,要載入ApplicationContext以使用EJB組件, ContextJndiBeanFactoryLocator的默認實現基本上足夠了, 不過,當ApplicationContext需要載入多個bean,或這些bean初始化所需的時間或內存 很多的時候(例如Hibernate的SessionFactory的初始化),就有可能出問題,因為 每個EJB組件都有自己的副本。這種情況下,用戶會想重載 ContextJndiBeanFactoryLocator的默認實現,并使用其它 BeanFactoryLocator的變體,例如ContextSingleton 或者BeanFactoryLocator,他們可以載入并共享一個 BeanFactory或ApplicationContext來為多個EJB組件或其它客戶端所公用。這樣做 相當簡單,只需要給EJB添加類似于如下的代碼:
  
   /**
    * Override default BeanFactoryLocator implementation
    * 
    * @see javax.ejb.SessionBean#setSessionContext(javax.ejb.SessionContext)
    */
   public void setSessionContext(SessionContext sessionContext) {
       super.setSessionContext(sessionContext);
       setBeanFactoryLocator(ContextSingletonBeanFactoryLocator.getInstance());
       setBeanFactoryLocatorKey(ServicesConstants.PRIMARY_CONTEXT_ID);
   }

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人精品电影| 国产精品欧美激情| 久久av在线播放| 日本精品va在线观看| 成人av色在线观看| 日韩欧美国产视频| 久久精品久久久久电影| 国产精品入口日韩视频大尺度| 成人午夜在线视频一区| 97久久久免费福利网址| 久久久亚洲精品视频| 在线观看精品自拍私拍| 国产精品一区二区av影院萌芽| 久久在线精品视频| 亚洲已满18点击进入在线看片| 亚洲另类激情图| 尤物yw午夜国产精品视频明星| 久久亚洲精品中文字幕冲田杏梨| 久久精品国产清自在天天线| 欧美在线观看视频| 九九精品在线视频| 亚洲天天在线日亚洲洲精| 91中文在线观看| 久久91超碰青草是什么| 国产香蕉一区二区三区在线视频| 国产精品久久久精品| 亚洲在线视频观看| 欧美色欧美亚洲高清在线视频| 亚洲va欧美va在线观看| 午夜精品久久久久久久久久久久| 亚洲自拍偷拍区| 91成人福利在线| 欧美精品在线第一页| 正在播放亚洲1区| 欧美wwwxxxx| 福利二区91精品bt7086| 成人写真福利网| 久久精品亚洲国产| 日韩av最新在线| 国产亚洲aⅴaaaaaa毛片| 日韩av免费看网站| 色噜噜久久综合伊人一本| 日本久久久久久| 欧洲美女7788成人免费视频| 欧美一级片久久久久久久| 精品动漫一区二区三区| 国产成人一区二区三区小说| 国产极品精品在线观看| 国产有码在线一区二区视频| 欧美福利视频网站| 欧美日产国产成人免费图片| 中文字幕久久久av一区| 国产日韩欧美中文在线播放| 欧美激情视频免费观看| 亚洲精品在线看| 精品国产欧美一区二区五十路| 日本一区二区三区在线播放| 亚洲人成网7777777国产| 97超碰国产精品女人人人爽| 亚洲精品日韩久久久| 欧美日韩成人在线观看| 欧美性生交xxxxx久久久| 高清欧美一区二区三区| 日韩一区二区三区国产| 欧美一区二区三区艳史| 国产精品电影在线观看| 精品国偷自产在线视频99| 91在线免费观看网站| 日韩福利伦理影院免费| 亚洲精品小视频| 国模视频一区二区三区| 久久人人爽人人爽人人片av高清| 国产精品美女久久| 色99之美女主播在线视频| 日韩av电影手机在线观看| 国产精品高潮呻吟久久av野狼| 国产欧美中文字幕| 成人国产精品免费视频| 疯狂做受xxxx欧美肥白少妇| 国产精品入口尤物| 欧美裸体xxxxx| 国产午夜精品一区二区三区| 久久综合亚洲社区| 亚洲精品资源在线| 人体精品一二三区| 国产精品丝袜一区二区三区| 亚洲区在线播放| 日韩精品视频免费| 国产精品视频1区| 久久这里有精品视频| 精品久久久精品| 亚洲视频专区在线| 欧美色图在线视频| 亚洲天堂视频在线观看| 亚洲男人的天堂在线| 色综合亚洲精品激情狠狠| 欧美性极品xxxx做受| 欧美日本啪啪无遮挡网站| 亚洲成人亚洲激情| 久久久久久久久久久网站| 欧美在线亚洲一区| 亚洲精品视频网上网址在线观看| 亚洲精品成人免费| 日韩欧美在线第一页| 一夜七次郎国产精品亚洲| 欧美在线视频网站| 亚洲欧美一区二区三区情侣bbw| 亚洲女人天堂视频| 亚洲成人av中文字幕| 2019中文字幕在线免费观看| 欧美洲成人男女午夜视频| 国产精品欧美激情在线播放| 亚洲理论电影网| 国产亚洲精品久久久久久| 国产成人精品久久久| 视频一区视频二区国产精品| 中文字幕在线日韩| 国产午夜精品一区理论片飘花| 国产成人精品视频| 欧美日韩亚洲系列| 亚洲第一精品久久忘忧草社区| 国产欧美日韩免费| 日韩欧美在线一区| 国产精品久久久久久av福利软件| 亚洲成年人在线播放| 亚洲最大av网站| 亚洲国产私拍精品国模在线观看| 成人性生交大片免费看视频直播| 亚洲色图第三页| 亚洲第一精品福利| 日本一区二区三区在线播放| 久久久久久久色| 久久夜色撩人精品| 国产精品免费视频xxxx| 亚洲区中文字幕| 亚洲一二在线观看| 久国内精品在线| 国产成人av网| 色偷偷综合社区| 亚洲精品永久免费| 91在线观看免费高清| 亚洲成人教育av| 欧美一级电影久久| 欧美大片免费观看在线观看网站推荐| 国内精品视频久久| 亚洲最大激情中文字幕| xxav国产精品美女主播| 国外成人免费在线播放| 国产精品欧美亚洲777777| www.精品av.com| 亚洲四色影视在线观看| 色无极影院亚洲| 国产精品爽爽爽爽爽爽在线观看| 亲爱的老师9免费观看全集电视剧| 久久视频免费观看| 中文字幕亚洲无线码在线一区| 欧美成人合集magnet| 日本精品一区二区三区在线播放视频| 国产偷国产偷亚洲清高网站| 亚洲激情视频在线| 久久av在线看| 日韩av电影手机在线| 91亚洲精品一区二区| 国产精品国产福利国产秒拍|