隨筆 - 0, 文章 - 75, 評論 - 0, 引用 - 0
          數據加載中……

          開發具有本地接口的無狀態session bean

          當通過遠程接口調用EJB時
          首先客戶端需要與ejb建立起socket通信,在通信管道上他們之間需要來回發送IIOP協議消息,因為數據要在網絡進行傳輸,存放數據的java對象必須要進行序列化
          bean" name="image_operate_51381323502849734" alt="開發具有本地接口的無狀態session bean" src="http://s9.sinaimg.cn/middle/8020e411tb3b7c768b068&690" width="690" height="151" real_src="http://s9.sinaimg.cn/middle/8020e411tb3b7c768b068&690">
          在這個過程中,有網絡通信的開銷、協議解析的開銷、對象序列化的開銷。因為ejb是分布式技術,它允許客戶端與ejb應用在不同一機器上面,所以這些性能開銷也是必然的



          但是在實際生產中,不可避免這種情況:客戶端與EJB應用運行在同一臺機器上的同一個jboss中
          那么這個時候客戶端是否還有必要跟ejb之間走上面的網絡通信呢?
          這個時候的客戶端與ejb是在同一個jvm內,他們之間完全可以通過內存進行交互,如果如此,完全可以避免上面流程的性能開銷,所以引入了——本地接口



          通過本地接口調用ejb,直接在內存交互,這樣可以避免因網絡通信所造成的各種性能開銷,但有一點需要注意:
          只有客戶端與EJB應用都在同一個JVM內運行的時候,才能調用本地接口,否則只能調用遠程接口
          什么情況下客戶端與EJB應用是在同一個JVM?
          只要客戶端與EJB發布在同一個jboss內,就可以認為他們在同一個JVM


          ---------------------------------------------------------------


          在原有的HelloWorld項目中,修改HelloWorldBean.java
          @Remote(HelloWorld.class)
          修改為@Local(HelloWorld.class) 就可完成本地接口
          具有本地接口的無狀態bean已經被開發


          運行ANT的deploy將EJB部署到jboss中,通過控制臺可以看到ejb已經成功部署



          當EJB部署成功,jboss會為這個本地接口,生成出一個JNDI名稱
          開發EJB的客戶端 http://blog.sina.com.cn/s/blog_8020e411010123yl.html博文中講述了
          jboss生成JNDI默認命名規則,這里不再贅述


          這里生成的JNDI名稱為:HelloWorldBean/local
          在客戶端,通過該JNDI名稱,使用本地接口,訪問EJB



          此時會報錯,原因是客戶端和EJB不在同一個JVM內



          新建一個web項目,將其部署在jboss下,使客戶端與EJB在同一個jboss中,方可使用本地接口


          新建一個Test.jsp,將原EJBClient客戶端代碼,復制進來


          并講類引入進來(<%@ page import="java.naming.*"%>)


          此時 HelloWorld helloWorld =
          (HelloWorld)cts.lookup("HelloWorldBean/local");的HelloWorld類不存在,由于不是同一個項目,所以需要將剛才的EJBClient的java Project導入進這個Web Project中


          選中這個EJBClient的Web項目,右鍵,Properties


          bean" name="image_operate_36961323505810812" alt="開發具有本地接口的無狀態session bean" src="http://s7.sinaimg.cn/middle/8020e411tb3b89e3f2726&690" real_src="http://s7.sinaimg.cn/middle/8020e411tb3b89e3f2726&690">


          選擇剛才的EJB java Project,點OK


          在Test.jsp頁面,完整的導入:
          <%@ page import="javax.naming.*,com.test.ejb3.HelloWorld"
          %>
          <body>
          <%

          try{
          InitialContext cts = new
          InitialContext();
          //根據EJB的JNDI名稱去尋找與這個名稱綁定的EJB的待承擔對象
          //如果找到了,就會返回給客戶端
          //在客戶端用接口文件去引用這個待承擔對象
          HelloWorld
          helloWorld =
          (HelloWorld)cts.lookup("HelloWorldBean/local");
          out.println(helloWorld.getClass().getName());
          //$Proxy3
          //通過這個對象,調用EJB業務方法
          out.println(helloWorld.sayHello("本地人"));
          //hello說:你好,世界!
          }catch(NamingException
          e){
          out.println(e.getMessage());
          }

          %>
          </body>


          此時客戶端應用已經開發完成,然后導出war文件


          bean" name="image_operate_68381323509925781" alt="開發具有本地接口的無狀態session bean" src="http://s11.sinaimg.cn/middle/8020e411tb3b8b5fd6c5a&690" width="506" height="538" real_src="http://s11.sinaimg.cn/middle/8020e411tb3b8b5fd6c5a&690">


          將war文件,拷貝到jboss的發布目錄下進行發布



          如果:


          InitialContext cts = new InitialContext();


          為Application Server指定了JNDI名稱,那此程序只能運行在這個Application Server中


          如不寫參數,則其構造函數自動尋找jndi的上下文信息,自動與其綁定



          要注意:在EJBClient的Web項目下,引用的HelloWorld接口,并沒有將它的class文件放入該web項目的classpath下


          原因是:當加載到HelloWorld類時,沒有找到它時,由于引用了HelloWorld
          JavaProject項目,EJB類加載器就會去它的classpath中尋找


          所以,當WEB應用和EJB應用部署在同一個JVM內時,并不需要在客戶端應用里面,放入EJB的接口類


          如果將EJB接口類放入進客戶端classpath中,有時會導致類型出圖問題



          企業中,很有可能客戶端和EJB是部署在同一個JBOSS中,也可能部署在不同機器上


          考慮到這兩點,就會選用遠程接口或本地接口



          返回到剛才的HelloWorld java Project程序:


          新建一個接口:


          //繼承HelloWorld的業務方法
          public interface HelloWorldLocal extends
          HelloWorld{


          }



          修改實現的bean:


          bean" name="image_operate_82261323514902937" alt="開發具有本地接口的無狀態session bean" src="http://s15.sinaimg.cn/middle/8020e411tb3b9b9ef4f6e&690" width="575" height="215" real_src="http://s15.sinaimg.cn/middle/8020e411tb3b9b9ef4f6e&690">
          讓他既有本地接口,也有遠程接口


          優先調用本地接口


          這樣就可以使:當客戶端與EJB在同一個JBOSS中,使用本地接口


          客戶端與EJB不在同一個JBOSS中,則使用遠程接口



          ------------------------------------------------------------------


          try{
          InitialContext cts = new
          InitialContext();
          HelloWorld helloWorld =
          (HelloWorld)cts.lookup("HelloWorldBean/remote");//使用遠程接口
          System.out.println(helloWorld.getClass().getName());
          //$Proxy3
          System.out.println(helloWorld.sayHello("明明"));
          //明明說:你好,世界!
          }catch(NamingException
          e){
          System.out.println(e.getMessage());
          }


          EJB與客戶端在同一個jboss中,也可用遠程接口訪問


          ------------------------------------------------------------------


          <body>
          <%

          try{
          InitialContext cts = new
          InitialContext();
          HelloWorldLocal helloWorld =
          (HelloWorldLocal)cts.lookup("HelloWorldBean/local"); //使用本地接口
          out.println(helloWorld.getClass().getName());
          //$Proxy3
          out.println(helloWorld.sayHello("本地人"));
          //本地人說:你好,世界!
          }catch(NamingException
          e){
          out.println(e.getMessage());
          }

          %>
          </body>


          在Web客戶端與EJB使用同一個jboss,可用本地接口

          posted on 2012-04-22 16:10 hantai 閱讀(129) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 华安县| 庆阳市| 扶风县| 无锡市| 偏关县| 梧州市| 密云县| 嘉兴市| 海南省| 海兴县| 高平市| 虹口区| 乌兰察布市| 卓资县| 武义县| 瑞金市| 南阳市| 三穗县| 宕昌县| 上林县| 古田县| 繁昌县| 靖州| 东方市| 恩施市| 大冶市| 锦州市| 拉孜县| 色达县| 芜湖市| 永福县| 河北省| 会昌县| 望谟县| 弋阳县| 遂宁市| 建水县| 怀来县| 五河县| 冀州市| 承德县|