細(xì)心!用心!耐心!

          吾非文人,乃市井一俗人也,讀百卷書(shū),跨江河千里,故申城一游; 一兩滴辛酸,三四年學(xué)業(yè),五六點(diǎn)粗墨,七八筆買(mǎi)賣(mài),九十道人情。

          BlogJava 聯(lián)系 聚合 管理
            1 Posts :: 196 Stories :: 10 Comments :: 0 Trackbacks

          JavaRMI入門(mén)實(shí)戰(zhàn)

           
          為通過(guò)網(wǎng)絡(luò)執(zhí)行其他機(jī)器上的代碼,傳統(tǒng)的方法不僅難以學(xué)習(xí),而且易出錯(cuò)。解決這個(gè)問(wèn)題的最佳方法是:某些對(duì)象正好位于另一臺(tái)機(jī)器,我們可以發(fā)送一條消息,并獲得返回結(jié)果,就像位于自己的本機(jī)器一樣。Java遠(yuǎn)程方法調(diào)用(RMI)特性使客戶(hù)機(jī)上運(yùn)行的程序可以調(diào)用遠(yuǎn)程服務(wù)器上的對(duì)象。遠(yuǎn)程方法調(diào)用特性使Java編程人員能夠在網(wǎng)絡(luò)環(huán)境中分布操作。
            
            下面介紹一下必要的步驟,創(chuàng)建自己的RMI對(duì)象。
            
            一、遠(yuǎn)程接口概念:
            RMI對(duì)接口有著強(qiáng)烈的依賴(lài)。在需要?jiǎng)?chuàng)建一個(gè)遠(yuǎn)程對(duì)象的時(shí)候,我們通過(guò)傳遞一個(gè)接口來(lái)隱藏基層的實(shí)施細(xì)節(jié)。所以客戶(hù)得到遠(yuǎn)程對(duì)象的一個(gè)句柄正好同一些本地的根代碼連接,有后者負(fù)責(zé)通過(guò)網(wǎng)絡(luò)通信。但我們并不關(guān)心這些事情,通過(guò)自己的接口句柄發(fā)送消息即可。
            
            創(chuàng)建一個(gè)遠(yuǎn)程接口時(shí),必須遵守下列規(guī)則:
            
            1) 遠(yuǎn)程接口必須為public屬性(不能有“包訪(fǎng)問(wèn)”;也就是說(shuō),他不能是“友好的”)。否則,一旦客戶(hù)試圖裝載一個(gè)實(shí)現(xiàn)了遠(yuǎn)程接口的遠(yuǎn)程對(duì)象,就會(huì)得到一個(gè)錯(cuò)誤。
            
            2) 遠(yuǎn)程接口必須擴(kuò)展接口java.rmi.Remote。
            
            3) 除與應(yīng)用程序本身有關(guān)的違例,遠(yuǎn)程接口中的每個(gè)方法都必須在自己的throws從句中聲明java.rmi.RemoteException.
            
            4) 作為參數(shù)或返回值傳遞的一個(gè)遠(yuǎn)程對(duì)象(不管是直接,還是本地對(duì)象中嵌入)必須聲明為遠(yuǎn)程接口,不可聲明為實(shí)施類(lèi)。
            
            下面是一個(gè)遠(yuǎn)程接口示例,
            
            //PerfectTimeI.java
            
            //The PerfectTime remote interface
            
            package test;
            
            import java.rmi.*;
            
            public interface PerfectTimeI extends Remote {
            
              long getPerfectTime() throws RemoteException;
            
            }
            
            它表面上與其他的接口類(lèi)似,只是對(duì)Remote進(jìn)行了擴(kuò)展,而且所有的方法都會(huì)“擲”出RemoteException.接口和方法都是Public的。
            
            編譯PerfectTimeI.java,生成PerfectTimeI.class(test是包,編譯時(shí)注意路徑)
            
            G:\RMI>javac test\PerfectTimeI.java
            
            二、遠(yuǎn)程接口的實(shí)施:
            服務(wù)器必須包含一個(gè)擴(kuò)展了UnicastRemoteObject類(lèi),并實(shí)現(xiàn)遠(yuǎn)程接口。這個(gè)類(lèi)也可以含有附加的方法,但客戶(hù)只能使用遠(yuǎn)程接口中的方法。因?yàn)榭蛻?hù)是指向接口的一個(gè)句柄,而不是它的哪個(gè)類(lèi)。
            
            必須為遠(yuǎn)程對(duì)象定義構(gòu)件器,即使只準(zhǔn)備定義一個(gè)默認(rèn)構(gòu)件器,用它調(diào)用基礎(chǔ)類(lèi)構(gòu)件器。必須把它明確地編寫(xiě)出來(lái),因?yàn)樗仨?#8220;擲”出RemoteException違例。
            
            下面列出遠(yuǎn)程接口PerfectTime的事實(shí)過(guò)程:他代表精確計(jì)時(shí)服務(wù)
            
            //PerfectTime.java
            
            //The implementation of the PerfectTime remote object
            
            package test;
            
            import java.net.*;
            
            import java.rmi.*;
            
            import java.rmi.registry.*;
            
            import java.rmi.server.*;
            
            public class PerfectTime extends UnicastRemoteObject implements PerfectTimeI
            
            {
            
            //默認(rèn)構(gòu)件器,也要“擲”出RemoteException違例。
            
              public PerfectTime() throws RemoteException {
            
                super();
            
              }
            
            public long getPerfectTime() throws RemoteException {
            
              return System.currentTimeMillis();
            
            }
            
            public static void main(String[] args) {
            
            /*創(chuàng)建和安裝一個(gè)安全管理器,令其支持RMI.作為Java開(kāi)發(fā)包的一部分,適用于RMI唯一一個(gè)是RMISecurityManager.*/
            
              System.setSecurityManager(new RMISecurityManager());
            
              try {
            
              /*創(chuàng)建遠(yuǎn)程對(duì)象的一個(gè)或多個(gè)實(shí)例,下面是PerfectTime對(duì)象*/
            
                PerfectTime pt = new PerfectTime();
            
              /*向RMI遠(yuǎn)程對(duì)象注冊(cè)表注冊(cè)至少一個(gè)遠(yuǎn)程對(duì)象。一個(gè)遠(yuǎn)程對(duì)象擁有的方法即可生成指向其他遠(yuǎn)程對(duì)象的句柄,這樣,客戶(hù)到注冊(cè)表里訪(fǎng)問(wèn)一次,得到第一個(gè)遠(yuǎn)程對(duì)象即可.*/
            
                Naming.bind("PerfectTime", pt);
            
                System.out.println("Ready to do Time");
            
              } catch (Exception e) {
            
                e.printStackTrace();
            
              }
            
            }
            
            }
            
            編譯PerfectTime.java,生成PerfectTime.class(test是包,編譯時(shí)注意路徑)
            
            G:\RMI>javac test\PerfectTime.java
            
            三、創(chuàng)建根和干:
             創(chuàng)建RemoteObject的主干和框架。要完成這個(gè)工作可使用rmic編譯器,rmic編譯器生成遠(yuǎn)程對(duì)象的存根和骨架。存根(Stub)是遠(yuǎn)程對(duì)象在客戶(hù)端的代理,它將RMI調(diào)用傳遞給服務(wù)器端的骨架(Skeleton),后者負(fù)責(zé)將該調(diào)用傳遞給實(shí)際的遠(yuǎn)程方法輸入如下:
            
            G:\RMI>rmic -d G:\RMI test.PerfectTime
            
             執(zhí)行這個(gè)命令,
            
            若rmic成功運(yùn)行,test目錄里就會(huì)多出兩個(gè)新類(lèi):
            
            PerfectTime_Stub.class
            
            PerfectTime_Skel.class
            
            它們分別對(duì)應(yīng)的是根(stub)和干(skeleton).
            
            四、使用遠(yuǎn)程對(duì)象:
            RMI全部的宗旨就是可能簡(jiǎn)化遠(yuǎn)程接口對(duì)象的使用。我們客戶(hù)程序中要做的唯一一件額外事情是查找從服務(wù)器取回遠(yuǎn)程接口。下面就是編寫(xiě)的Java程序:將消息發(fā)給對(duì)象:
            
            //DisplayPerfectTime.java
            
            //Users remote object PerfectTime
            
            package test;
            
            import java.rmi.*;
            
            import java.rmi.registry.*;
            
            public class DisplayPerfectTime {
            
            /*** DisplayPerfectTime 構(gòu)造子注解。*/
            
            public DisplayPerfectTime() {
            
              super();
            
            }
            
            public static void main(String[] args) {
            
              System.setSecurityManager(new RMISecurityManager());
            
              try {
            
                PerfectTimeI t = (PerfectTimeI) Naming.lookup("PerfectTime");
            
                for (int i = 0; i < 10; i++) {
            
                  System.out.println("PerfectTime:" + t.getPerfectTime());
            
                }
            
              } catch (Exception e) {
            
                e.printStackTrace();
            
              }
            
            }
            
            }
            
            編譯DisplayPerfectTime.java.
            
            G:\RMI>javac test\DisplayPerfectTime.java
            
            五、啟動(dòng)注冊(cè)并運(yùn)行代碼:
            在運(yùn)行PerfectTime類(lèi)和DisplayPectTime類(lèi)之前,用戶(hù)必須首先在將要宿主PerfectTime的計(jì)算機(jī)上啟動(dòng)RMI注冊(cè)(Registry)程序,即使將要運(yùn)行PerfectTime的計(jì)算機(jī)與運(yùn)行DisplayPerfectTime的是同一臺(tái)機(jī)器,這一步也是必須的。注冊(cè)表服務(wù)器的名字是rmiregistry.在32位Windows環(huán)境中,可使用: start rmiregistry 令其在后臺(tái)運(yùn)行。然后分別開(kāi)兩個(gè)不同的進(jìn)程運(yùn)行Server端和Client端:?jiǎn)?dòng)注冊(cè)表服務(wù)器:
            
            G:\RMI>start rmiregistry
            
            綁定PerfectTime到注冊(cè),運(yùn)行服務(wù)端程序:在Windows下,輸入下列命令,在后臺(tái)啟動(dòng)PerfectTime程序:
            
            G:\RMI>java test.PerfectTime
            
            Ready to do Time
            
            運(yùn)行客戶(hù)端程序:如下
            
            G:\RMI>java test.DisplayPerfectTime
            
            PerfectTime:961722589649
            
            PerfectTime:961722589669
            
            PerfectTime:961722589679
            
            PerfectTime:961722589679
            
            PerfectTime:961722589689
            
            PerfectTime:961722589689
            
            PerfectTime:961722589689
            
            PerfectTime:961722589699
            
            PerfectTime:961722589699
          posted on 2007-05-06 12:35 張金鵬 閱讀(84) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 上思县| 轮台县| 通辽市| 敖汉旗| 威宁| 溧水县| 富民县| 翁牛特旗| 清流县| 怀远县| 武功县| 宽甸| 临城县| 双城市| 饶阳县| 镇坪县| 沙坪坝区| 龙山县| 三明市| 长丰县| 肃南| 衡阳县| 遵化市| 潮州市| 阿鲁科尔沁旗| 米脂县| 静安区| 广西| 饶平县| 阿拉尔市| 中山市| 新昌县| 英山县| 重庆市| 林西县| 左权县| 休宁县| 瑞安市| 泉州市| 乌兰浩特市| 古田县|