隨筆-159  評論-114  文章-7  trackbacks-0
          簡單來說,要實現A機器上JVM上運行的Java程序,遠程調用B機器上JVM上的Java程序,計算完畢,返回給A機器。

          在沒有RMI的情況下,我們使用普通的網絡傳輸技術能完成么?當然,兩種選擇,Socket直接通訊,將參數傳給B,B在通過Socket返還給調用者。或者通過Servlet也可以遠程調用阿。

          那么這樣解決問題時沒有問題,但對于A和B來說,代碼量、程序復用程序、維護性都不會太理想。

          如果能讓調用者不知道網絡操作,實現對于用戶透明,也就是像調用本地一樣,對象名.方法名。

          那么就是RMI規范涉及到一些接口。

          面向接口的編程方式,就可以達到代碼的實現與聲明分離。

          這樣用戶就只關心接口了。很多細節讓遵守規范(也就是一些編寫好的工具)的實現類去完成吧。[就是Stub和Skeleton]

          那么就先定一個用戶A要知道怎么用,B要知道方法簽名完成實現,的同一接口吧。

          import?java.rmi.*;

          public?interface?Compute?extends?Remote{
          ????
          ????
          public?double?add(double?a,double?b)?throws?RemoteException;
          ????
          }

          兩點要求

          1,繼承標記接口Remote。

          identify interfaces whose methods may be invoked from a non-local virtual machine.

          標識該接口可以被非本地VM調用唄。

          2,里面每個方法都要拋出RemoteException


          業務接口的實現類,也就是做實事的類

          import?java.rmi.server.*;
          import?java.rmi.*;

          public?class?ComputeImpl?extends?UnicastRemoteObject?implements?Compute
          {
          ????
          //要在構造方法拋出異常
          ????public?ComputeImpl()?throws?RemoteException{}
          ????
          ????
          public?double?add(double?a,double?b){
          ????????
          return?a+b;
          ????}

          }


          =====================
          javac *.class

          rmic -keep ComputeImpl
          帶參數,可以保留Stub和Skeleton源碼。

          通過ComputeImpl的實現類來生成負責通訊的Stub(存根)和Skeleton(框架)

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

          那么就是要把這個對象綁定到一個端口上。

          以便別人來使用

          編寫一個Server

          import?java.rmi.*;

          public?class?Server
          {

          ????
          public?static?void?main(String[]?args)?throws?Exception
          ????
          {
          ????????ComputeImpl?c?
          =?new?ComputeImpl();
          ????????Naming.bind(
          "rmi://localhost:8888/compute",c);//compute別名
          ????}


          }

          客戶端

          import?java.rmi.*;

          public?class?Client
          {
          ????
          public?static?void?main(String[]?args)?throws?Exception
          ????
          {
          ????????Compute?c?
          =?(Compute)Naming.lookup("rmi://localhost:8888/compute");//rmiregistry首先響應
          ????????
          //實際c是Stub對象
          ????????System.out.println(c.getClass());
          ????????System.out.println(c.add(
          12.3,34));
          ????}
          ???
          }


          ?看到沒有,客戶端通過rmi協議到服務器上尋找/compute資源對象。那個Naming是RMI專用,不是JNDI。

          那么Server類并沒有負責監聽阿。

          哦,最后有一個強大的工具在JAVA_HOME/bin/下,叫做rmiregistry,專門負責監聽固定端口上,rmi協議的請求。

          =================
          rmiregistry 8888

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

          啟動Server,綁定遠程對象阿

          java Server

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

          啟動一個Client,調用一下

          java Client

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

          rmi.jpg

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

          另外一些小問題

          由于rmiregistry 工具的不斷強大,jdk1.4已經可以不再使用skeleton,到1.5,根本就不生成skeleton了。

          rmiregistry可以充當skeleton角色完成功能。

          記住EJB中,還不行,因為沒有rmiregistry工具了。呵呵,明白了?

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

          所以什么呢,RMI就是一種代理模式的應用Stub,就是實際實現類的客戶代理。

          但需要統一的接口,才能對于用戶、調用者透明啊!

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


          我說的比較通俗。還有很多深刻的東西。

          posted on 2006-03-19 22:42 北國狼人的BloG 閱讀(1338) 評論(0)  編輯  收藏 所屬分類: 達內學習總結
          主站蜘蛛池模板: 浦城县| 新田县| 泸定县| 凤翔县| 高邮市| 龙井市| 云南省| 六枝特区| 读书| 洪江市| 福清市| 茶陵县| 株洲县| 威海市| 五大连池市| 平塘县| 福州市| 花莲市| 宁远县| 衡水市| 安多县| 兰溪市| 乾安县| 金川县| 新闻| 宝兴县| 峨边| 兴化市| 招远市| 宾阳县| 绥阳县| 宜兰县| 沭阳县| 北川| 清原| 清镇市| 花垣县| 宣威市| 绥江县| 邵东县| 龙陵县|