隨筆-159  評(píng)論-114  文章-7  trackbacks-0
          為了解決RMI無法解決的分布式事務(wù)控制,安全,并發(fā)等問題。

          EJB解決訪問就是一種可以高校的開發(fā)分布式應(yīng)用的解決方案。

          編寫EJB,其實(shí)只需要編寫2個(gè)接口和一個(gè)Bean類,和一個(gè)部屬描述就可以了。

          服務(wù)接口:

          import?javax.ejb.*;
          import?java.rmi.*;
          //business???remote
          public?interface?Compute?extends?EJBObject{
          ????
          public?double?add(double?a,double?b)?throws?RemoteException;
          }


          Home接口:

          import?javax.ejb.*;
          import?java.rmi.*;

          public?interface?ComputeHome?extends?EJBHome{
          ????
          public?Compute?create()?throws?RemoteException,CreateException;
          }

          Bean,業(yè)務(wù)邏輯實(shí)現(xiàn)的地方

          import?javax.ejb.*;

          public?class?ComputeBean?implements?SessionBean
          {
          ????
          public?void?setSessionContext(SessionContext?ctx)
          ???????????????????????
          throws?EJBException,
          ??????????????????????????????java.rmi.RemoteException
          {
          ????}

          ????
          public?void?ejbRemove()
          ???????????????
          throws?EJBException,
          ??????????????????????java.rmi.RemoteException
          {
          ????}

          ????
          public?void?ejbActivate()
          ?????????????????
          throws?EJBException,
          ????????????????????????java.rmi.RemoteException
          {
          ????}

          ????
          public?void?ejbPassivate()
          ??????????????????
          throws?EJBException,
          ?????????????????????????java.rmi.RemoteException
          {
          ????}

          ????
          public?void?ejbCreate()?throws?CreateException{
          ????}

          ????
          public?double?add(double?a,double?b){
          ????????
          return?a*b;
          ????}

          }


          <?xml?version="1.0"?encoding="UTF-8"?>
          <!DOCTYPE?ejb-jar?PUBLIC?"-//Sun?Microsystems,?Inc.//DTD?Enterprise?JavaBeans?2.0//EN"?"http://java.sun.com/dtd/ejb-jar_2_0.dtd">
          <ejb-jar>
          ????
          <enterprise-beans>
          ????????
          <session>
          ????????????
          <display-name>Compute</display-name>
          ????????????
          <ejb-name>abc</ejb-name>

          ????????????
          <home>ComputeHome</home>
          ????????????
          <remote>Compute</remote>
          ????????????
          <ejb-class>ComputeBean</ejb-class>

          ????????????
          <session-type>Stateless</session-type>
          ????????????
          <transaction-type>Container</transaction-type>?????
          ????????
          </session>
          ????
          </enterprise-beans>
          ????
          <assembly-descriptor>
          ????????
          <container-transaction>
          ????????????
          <method>
          ????????????????
          <ejb-name>abc</ejb-name>
          ????????????????
          <method-name>*</method-name>
          ????????????
          </method>
          ????????????
          <trans-attribute>Required</trans-attribute>
          ????????
          </container-transaction>
          ????????
          ????
          </assembly-descriptor>
          </ejb-jar>

          JNDI的實(shí)現(xiàn)各個(gè)服務(wù)器的實(shí)現(xiàn)不同,所以需要依賴于服務(wù)器的一個(gè)xml。

          JNDI也是一種面向接口編程,工廠模式的典范。

          <?xml?version="1.0"?encoding="UTF-8"?>
          <!DOCTYPE?weblogic-ejb-jar?PUBLIC?'-//BEA?Systems,?Inc.//DTD?WebLogic?8.1.0?EJB//EN'?'http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd'>
          <weblogic-ejb-jar>
          ????
          <weblogic-enterprise-bean>
          ????????
          <ejb-name>abc</ejb-name>????????
          ????????
          <jndi-name>efg</jndi-name>
          ????
          </weblogic-enterprise-bean>
          </weblogic-ejb-jar>


          想編譯EJB,需要j2ee jar,那就用\bea\weblogic81\server\lib\weblogic.jar

          做一個(gè)META-INF放置兩個(gè)xml文件

          jar -cvf Compute.jar *.class META-INF/*.xml

          c創(chuàng)建,v看到它創(chuàng)建的過程,f文件名



          部屬EJB,看看Weblogic幫助吧。

          =============================

          那么會(huì)發(fā)現(xiàn)jar文件中并沒有出現(xiàn)_stub或者_(dá)skeleton文件阿,那是因?yàn)橛扇萜髟谶\(yùn)行EJB時(shí)動(dòng)態(tài)創(chuàng)建在容器內(nèi)部了。

          那么怎么才能看到呢?我們要分析阿。

          java weblogic.appc ejb.jar

          如果抱錯(cuò),在classpath中添加\jdk142_04\lib\tools.jar

          如果想看原文件的話,就是-keepgenerated

          rmi2.jpg

          ===============================

          開始分析EJB工作原理

          看下面一張圖,就清楚了,實(shí)際就是兩次RMI 調(diào)用。

          27229257.ejb2.jpg

          要細(xì)致來說。

          基本是這樣的。

          定義Home接口,主要是為讓客戶端有可能在創(chuàng)建EJB Bean對(duì)象時(shí),給予初始化。

          import?javax.ejb.*;
          import?java.rmi.*;

          public?interface?ComputeHome?extends?EJBHome{
          ????
          public?Compute?create()?throws?RemoteException,CreateException;
          }


          這只是一個(gè)接口,weblogic.appc會(huì)生成一個(gè)HomeImpl,并生成Stub和Skeleton對(duì)象。在客戶端JNDI查找時(shí),返回就是這個(gè)HomeImpl的Stub對(duì)象,注意類文件也會(huì)動(dòng)態(tài)下載的。

          create()與ejbcreate()方法是對(duì)應(yīng)的。

          可有參數(shù)。

          //Bean

          ???
          public?void?ejbCreate(String?param)?throws?CreateException?{
          ????????
          //?TODO?Auto-generated?method?stub
          ????????this.userName?=?param;
          ????}



          //Home

          public?com.infogo.interfaces.Shopping?create(java.lang.String?param)
          ??????
          throws?javax.ejb.CreateException,java.rmi.RemoteException;

          ===========

          那么客戶端實(shí)際調(diào)用的是HomeImpl的Stub對(duì)象的方法,通過網(wǎng)絡(luò)傳送到服務(wù)器上的Skeleton,Skeleton再調(diào)用真正的HomeImpl對(duì)象的方法,創(chuàng)建一個(gè)創(chuàng)建Bean對(duì)象放入實(shí)例池,Impl調(diào)用Bean的ejbcreate方法,初始化參數(shù)。

          并且HomeImpl,還要?jiǎng)?chuàng)建一個(gè)業(yè)務(wù)業(yè)務(wù)接口的實(shí)現(xiàn)類,并把業(yè)務(wù)接口實(shí)現(xiàn)類(EOImpl)對(duì)象的Stub返回給客戶端。

          客戶端拿到Stub,調(diào)用響應(yīng)服務(wù)方法(別忘了,真正的服務(wù)方法實(shí)現(xiàn)可是在Bean類里),所以調(diào)用Stub方法,通過網(wǎng)絡(luò)傳遞EOImpl的Skeleton對(duì)象,然后調(diào)用EOImpl的響應(yīng)方法。

          這是注意,EOImpl被稱為請(qǐng)求攔截器,因?yàn)樗鼤?huì)在這時(shí)察看ejb-jar.xml,看一看方法聲明的事務(wù)類型,并調(diào)用容器提供的API(安全、事務(wù)等)。所以這種服務(wù)器或者容器叫做隱式容器,它有工具生成的類來調(diào)用容器相關(guān)API。而不是用戶直接調(diào)用。

          在EOImpl調(diào)用完容器API之后,就會(huì)調(diào)用Bean的業(yè)務(wù)方法。

          最后將接口-Skeleton-Stub-客戶端。

          所以是兩次RMI調(diào)用。

          這就是EJB工作原理。

          import?javax.naming.*;
          import?java.util.*;
          import?javax.rmi.*;


          public?class?Client
          {
          ????
          public?static?void?main(String[]?args)?throws?Exception
          ????
          {
          ????????Hashtable?hash?
          =?new?Hashtable();
          ????????hash.put(Context.INITIAL_CONTEXT_FACTORY,
          "weblogic.jndi.WLInitialContextFactory");
          ????????hash.put(Context.PROVIDER_URL,
          "t3://localhost:7001");
          ????????InitialContext?ic?
          =?new?InitialContext(hash);
          ????????
          ????????ComputeHome?home?
          =?(ComputeHome)ic.lookup("efg");
          ????????
          ????????
          //(ComputeHome)ProtableRemoteObject.narrow(ic.lookup("efg"),ComputeHome.class);
          ???????/*
          ????????*?客戶端從服務(wù)器獲得HomeImpl_stub?.class文件,并獲得HomeImpl_stub的對(duì)象
          ????????*?
          ????????*?home.create()-->HomeImpl_stub.create()-->網(wǎng)絡(luò)發(fā)送-->HomeImpl_skel.create()-->HomeImpl創(chuàng)建ComputeBean對(duì)象-->ComputeBean.ejbcreate()&&HomeImpl還要?jiǎng)?chuàng)建EOImpl_stub對(duì)象,返回HomeImpl_skel--->[網(wǎng)絡(luò)往回傳輸]--->HomeImpl_stub--->客戶端拿到EOImpl_stub對(duì)象。
          ????????*
          ????????*?這時(shí)完成了第一次rmi
          ????????*
          ????????*?c獲得了EOImpl_Stub對(duì)象,
          ????????*?
          ????????*?c.add(32,32)---->?EOImpl_Stub.add()--->網(wǎng)絡(luò)發(fā)送--->EOImpl_Skel.add()--->EOImpl--->[根據(jù)xml描述的事務(wù),進(jìn)行事務(wù)描述]--->判斷add方法是否開始事務(wù)--->調(diào)用創(chuàng)建好Bean對(duì)象的add方法---->方法結(jié)果給EOImpl_Skel---->網(wǎng)絡(luò)往回傳輸---->EOImpl_Stub----客戶端拿到結(jié)果。
          ????????*
          ????????*?第二次rmi完成。
          ????????
          */

          ????????
          ????????
          ????????
          ????????Compute?c?
          =?home.create();
          ????????System.out.println(c.add(
          32,32));
          ????????
          ????}
          ???
          }


          posted on 2006-03-19 23:45 北國狼人的BloG 閱讀(972) 評(píng)論(0)  編輯  收藏 所屬分類: 達(dá)內(nèi)學(xué)習(xí)總結(jié)
          主站蜘蛛池模板: 大新县| 仙游县| 电白县| 台山市| 兴安盟| 麦盖提县| 西林县| 牡丹江市| 东兴市| 焉耆| 从化市| 罗江县| 岳西县| 靖宇县| 宜宾县| 永城市| 搜索| 正安县| 鄱阳县| 临潭县| 营山县| 凤山市| 宜黄县| 黔江区| 定州市| 云龙县| 兴隆县| 五大连池市| 永清县| 高青县| 桑日县| 新闻| 文成县| 滨州市| 施秉县| 嘉禾县| 兴宁市| 漳州市| 胶州市| 南宫市| 休宁县|