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

          EJB解決訪問就是一種可以高校的開發分布式應用的解決方案。

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

          服務接口:

          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,業務邏輯實現的地方

          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的實現各個服務器的實現不同,所以需要依賴于服務器的一個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

          做一個META-INF放置兩個xml文件

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

          c創建,v看到它創建的過程,f文件名



          部屬EJB,看看Weblogic幫助吧。

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

          那么會發現jar文件中并沒有出現_stub或者_skeleton文件阿,那是因為由容器在運行EJB時動態創建在容器內部了。

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

          java weblogic.appc ejb.jar

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

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

          rmi2.jpg

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

          開始分析EJB工作原理

          看下面一張圖,就清楚了,實際就是兩次RMI 調用。

          27229257.ejb2.jpg

          要細致來說。

          基本是這樣的。

          定義Home接口,主要是為讓客戶端有可能在創建EJB Bean對象時,給予初始化。

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

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


          這只是一個接口,weblogic.appc會生成一個HomeImpl,并生成Stub和Skeleton對象。在客戶端JNDI查找時,返回就是這個HomeImpl的Stub對象,注意類文件也會動態下載的。

          create()與ejbcreate()方法是對應的。

          可有參數。

          //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;

          ===========

          那么客戶端實際調用的是HomeImpl的Stub對象的方法,通過網絡傳送到服務器上的Skeleton,Skeleton再調用真正的HomeImpl對象的方法,創建一個創建Bean對象放入實例池,Impl調用Bean的ejbcreate方法,初始化參數。

          并且HomeImpl,還要創建一個業務業務接口的實現類,并把業務接口實現類(EOImpl)對象的Stub返回給客戶端。

          客戶端拿到Stub,調用響應服務方法(別忘了,真正的服務方法實現可是在Bean類里),所以調用Stub方法,通過網絡傳遞EOImpl的Skeleton對象,然后調用EOImpl的響應方法。

          這是注意,EOImpl被稱為請求攔截器,因為它會在這時察看ejb-jar.xml,看一看方法聲明的事務類型,并調用容器提供的API(安全、事務等)。所以這種服務器或者容器叫做隱式容器,它有工具生成的類來調用容器相關API。而不是用戶直接調用。

          在EOImpl調用完容器API之后,就會調用Bean的業務方法。

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

          所以是兩次RMI調用。

          這就是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);
          ???????/*
          ????????*?客戶端從服務器獲得HomeImpl_stub?.class文件,并獲得HomeImpl_stub的對象
          ????????*?
          ????????*?home.create()-->HomeImpl_stub.create()-->網絡發送-->HomeImpl_skel.create()-->HomeImpl創建ComputeBean對象-->ComputeBean.ejbcreate()&&HomeImpl還要創建EOImpl_stub對象,返回HomeImpl_skel--->[網絡往回傳輸]--->HomeImpl_stub--->客戶端拿到EOImpl_stub對象。
          ????????*
          ????????*?這時完成了第一次rmi
          ????????*
          ????????*?c獲得了EOImpl_Stub對象,
          ????????*?
          ????????*?c.add(32,32)---->?EOImpl_Stub.add()--->網絡發送--->EOImpl_Skel.add()--->EOImpl--->[根據xml描述的事務,進行事務描述]--->判斷add方法是否開始事務--->調用創建好Bean對象的add方法---->方法結果給EOImpl_Skel---->網絡往回傳輸---->EOImpl_Stub----客戶端拿到結果。
          ????????*
          ????????*?第二次rmi完成。
          ????????
          */

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


          posted on 2006-03-19 23:45 北國狼人的BloG 閱讀(972) 評論(0)  編輯  收藏 所屬分類: 達內學習總結
          主站蜘蛛池模板: 澎湖县| 天水市| 镇远县| 安乡县| 保山市| 阿坝| 东乡族自治县| 新竹市| 轮台县| 永登县| 衡东县| 江阴市| 汪清县| 印江| 双峰县| 望都县| 高陵县| 天长市| 南充市| 无极县| 新昌县| 永宁县| 牙克石市| 随州市| 台北县| 兰坪| 四子王旗| 友谊县| 绩溪县| 康平县| 岚皋县| 双江| 玛曲县| 万州区| 寿光市| 松江区| 哈密市| 山阳县| 资阳市| 东辽县| 嘉义县|