隨筆 - 0, 文章 - 75, 評論 - 0, 引用 - 0
          數(shù)據(jù)加載中……

          開發(fā)具有本地接口的無狀態(tài)session bean

          當(dāng)通過遠(yuǎn)程接口調(diào)用EJB時(shí)
          首先客戶端需要與ejb建立起socket通信,在通信管道上他們之間需要來回發(fā)送IIOP協(xié)議消息,因?yàn)閿?shù)據(jù)要在網(wǎng)絡(luò)進(jìn)行傳輸,存放數(shù)據(jù)的java對象必須要進(jìn)行序列化
          bean" name="image_operate_51381323502849734" alt="開發(fā)具有本地接口的無狀態(tài)session bean" src="http://s9.sinaimg.cn/middle/8020e411tb3b7c768b068&690" width="690" height="151" real_src="http://s9.sinaimg.cn/middle/8020e411tb3b7c768b068&690">
          在這個(gè)過程中,有網(wǎng)絡(luò)通信的開銷、協(xié)議解析的開銷、對象序列化的開銷。因?yàn)?font color="#f70e02">ejb是分布式技術(shù),它允許客戶端與ejb應(yīng)用在不同一機(jī)器上面,所以這些性能開銷也是必然的。



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



          通過本地接口調(diào)用ejb,直接在內(nèi)存交互,這樣可以避免因網(wǎng)絡(luò)通信所造成的各種性能開銷,但有一點(diǎn)需要注意:
          只有客戶端與EJB應(yīng)用都在同一個(gè)JVM內(nèi)運(yùn)行的時(shí)候,才能調(diào)用本地接口,否則只能調(diào)用遠(yuǎn)程接口。
          什么情況下客戶端與EJB應(yīng)用是在同一個(gè)JVM?
          只要客戶端與EJB發(fā)布在同一個(gè)jboss內(nèi),就可以認(rèn)為他們在同一個(gè)JVM


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


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


          運(yùn)行ANT的deploy將EJB部署到j(luò)boss中,通過控制臺(tái)可以看到ejb已經(jīng)成功部署



          當(dāng)EJB部署成功,jboss會(huì)為這個(gè)本地接口,生成出一個(gè)JNDI名稱
          開發(fā)EJB的客戶端 http://blog.sina.com.cn/s/blog_8020e411010123yl.html博文中講述了
          jboss生成JNDI默認(rèn)命名規(guī)則,這里不再贅述


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



          此時(shí)會(huì)報(bào)錯(cuò),原因是客戶端和EJB不在同一個(gè)JVM內(nèi)



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


          新建一個(gè)Test.jsp,將原EJBClient客戶端代碼,復(fù)制進(jìn)來


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


          此時(shí) HelloWorld helloWorld =
          (HelloWorld)cts.lookup("HelloWorldBean/local");的HelloWorld類不存在,由于不是同一個(gè)項(xiàng)目,所以需要將剛才的EJBClient的java Project導(dǎo)入進(jìn)這個(gè)Web Project中


          選中這個(gè)EJBClient的Web項(xiàng)目,右鍵,Properties


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


          選擇剛才的EJB java Project,點(diǎn)OK


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

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

          %>
          </body>


          此時(shí)客戶端應(yīng)用已經(jīng)開發(fā)完成,然后導(dǎo)出war文件


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


          將war文件,拷貝到j(luò)boss的發(fā)布目錄下進(jìn)行發(fā)布



          如果:


          InitialContext cts = new InitialContext();


          為Application Server指定了JNDI名稱,那此程序只能運(yùn)行在這個(gè)Application Server中


          如不寫參數(shù),則其構(gòu)造函數(shù)自動(dòng)尋找jndi的上下文信息,自動(dòng)與其綁定



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


          原因是:當(dāng)加載到HelloWorld類時(shí),沒有找到它時(shí),由于引用了HelloWorld
          JavaProject項(xiàng)目,EJB類加載器就會(huì)去它的classpath中尋找


          所以,當(dāng)WEB應(yīng)用和EJB應(yīng)用部署在同一個(gè)JVM內(nèi)時(shí),并不需要在客戶端應(yīng)用里面,放入EJB的接口類


          如果將EJB接口類放入進(jìn)客戶端classpath中,有時(shí)會(huì)導(dǎo)致類型出圖問題



          企業(yè)中,很有可能客戶端和EJB是部署在同一個(gè)JBOSS中,也可能部署在不同機(jī)器上


          考慮到這兩點(diǎn),就會(huì)選用遠(yuǎn)程接口或本地接口



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


          新建一個(gè)接口:


          //繼承HelloWorld的業(yè)務(wù)方法
          public interface HelloWorldLocal extends
          HelloWorld{


          }



          修改實(shí)現(xiàn)的bean:


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


          優(yōu)先調(diào)用本地接口


          這樣就可以使:當(dāng)客戶端與EJB在同一個(gè)JBOSS中,使用本地接口


          客戶端與EJB不在同一個(gè)JBOSS中,則使用遠(yuǎn)程接口



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


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


          EJB與客戶端在同一個(gè)jboss中,也可用遠(yuǎn)程接口訪問


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


          <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使用同一個(gè)jboss,可用本地接口

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


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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 云梦县| 曲靖市| 通山县| 轮台县| 中宁县| 重庆市| 建宁县| 峨边| 江都市| 酉阳| 石楼县| 嘉兴市| 上高县| 大田县| 丰县| 五常市| 奈曼旗| 乌鲁木齐县| 松江区| 确山县| 进贤县| 洪泽县| 怀仁县| 科尔| 垫江县| 崇仁县| 庄浪县| 卢氏县| 姜堰市| 盐源县| 金门县| 仁怀市| 左权县| 余江县| 自贡市| 潼关县| 绩溪县| 孝感市| 驻马店市| 房产| 沛县|