對 RMI 的簡單理解
?
RMI (遠程方法)是 Java 平臺中建立分布式計算的基礎, 2 年前我剛開始接觸 J2EE 時,怎么看書都是不得要領,最近這幾天閑著沒事又翻了翻以前沒有看懂的書,突然之間頓悟了。
一、 簡單的 RMI 示例:
要快速入門,最簡單的方法就是看簡單的例子。下面是我寫的一個簡單的示例:
首先,定義一個接口 IServer ,代碼如下:
IServer.java
需要注意的是,這個接口從java.rmi.Remote接口擴展,并且這個接口中定義的方法都需要拋出java.rmi.RemoteException異常。
接著,我們要根據這個接口來實現自己的服務器對象,所謂服務器對象,就是我們大腦中想的遠程對象,這個對象中定義的方法都是被別人來調用的。代碼如下:
ServerImp.java
這個類很容易理解, doSomeThing() 方法只簡單的輸出被調用的信息。唯一的難點就在 main() 函數中,我們通過 java.rmi.Naming.rebind() 把我們的遠程對象注冊到 rmi 注冊表中,這樣,別人就可以通過 java.rmi.Naming.lookup() 來查找我們的遠程對象。那么, rmi 注冊表在哪里呢? J2SDK 的 bin 目錄下有一個程序 rmiregistry ,運行它就可以得到一個注冊表進程,我們可以通過它來綁定或者查找遠程對象, java.rmi.Naming.rebind 函數的第一個參數就是要指定注冊表進程的位置,因為我這里運行在自己的機器上,所以是 //localhost/ ,如果是在別的機器上,可以用 IP 地址代替。
最后,我們寫一個客戶機,來調用這個遠程對象的方法。代碼如下:
Client.java
可以看到,我們的客戶端程序只用到了 IServer 接口,而不需要 ServerImp 類,它只通過 java.rmi.Naming.lookup() 來查找遠程對象的引用。
下面,我們就可以開始測試我們的程序了。先編譯以上程序,然后:
第一步,要先啟動 Rmi 注冊表,如下:
第二步,使用 rmic 對 ServerImp.class 進行編譯,生成代理類 ServerImp_Stub.class ,如下:
第三步,啟動服務器端程序,如下:
第四步,啟動客戶端程序,我們多調用幾次,如下:
這個時候,我們再看看服務器端是什么反應:
可以看到,服務器端的方法被調用,在服務器端的控制臺上打印出了這樣幾行消息。
下面,我們使用一個簡單的圖表來表示客戶機、服務器和 RMI 注冊表之間的關系,綠色的數字代表順序:
二、參數傳遞 前面的例子沒有涉及到參數的傳遞。如果我們需要向遠程方法傳遞參數,或者要從遠程方法接受返回值,是不是有什么特殊的約定呢?不錯,如果我們要在客戶機和服務器之間傳遞參數,則該對象要么是實現Serializable接口的對象,要么是擴展自UnicastRemoteObject的對象,這兩種對象是有差別的。 如果參數是實現Serializable接口的對象,則該對象是按值傳遞的,也就是把這整個對象傳遞到遠程方法中。請看下面的例子,我們定義了一個ISerializableWorker接口,擴展自Serializable接口,客戶端創建一個SerializableWorkerImp對象wk,并把它傳遞到服務器端,服務器端調用wk.work()方法,這個方法在服務器端執行,這就說明了我們成功把這個對象傳遞到了服務器端。服務器端返回的String對象,也可以成功傳遞到客戶端。ISerializableWorker.java
然后,我們需要在服務器端程序中載入安全管理器,我們這里使用默認的RMISecurityManager,下面是經過修改了的ServerImp.java中的mian()函數:
Powered by: BlogJava Copyright © 京山游俠