基于Java的企業(yè)分布式應(yīng)用
發(fā)表時(shí)間:2024-01-10 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]隨著電力企業(yè)信息化建設(shè)的不斷深入和發(fā)展,企業(yè)內(nèi)部和企業(yè)與企業(yè)之間對(duì)信息、對(duì)數(shù)據(jù)的交換量大大增加,這些信息與數(shù)據(jù)越來越需要在不同的計(jì)算機(jī)網(wǎng)絡(luò)間傳送和交流。同時(shí),由于各單位、各部門之間的現(xiàn)存的計(jì)算機(jī)網(wǎng)絡(luò)硬件設(shè)備與操作系統(tǒng)千差萬別,應(yīng)用水平也參差不齊,因此,開發(fā)出跨平臺(tái)、可移植、高效安全的網(wǎng)絡(luò)分布式應(yīng)用...
隨著電力企業(yè)信息化建設(shè)的不斷深入和發(fā)展,企業(yè)內(nèi)部和企業(yè)與企業(yè)之間對(duì)信息、對(duì)數(shù)據(jù)的交換量大大增加,這些信息與數(shù)據(jù)越來越需要在不同的計(jì)算機(jī)網(wǎng)絡(luò)間傳送和交流。同時(shí),由于各單位、各部門之間的現(xiàn)存的計(jì)算機(jī)網(wǎng)絡(luò)硬件設(shè)備與操作系統(tǒng)千差萬別,應(yīng)用水平也參差不齊,因此,開發(fā)出跨平臺(tái)、可移植、高效安全的網(wǎng)絡(luò)分布式應(yīng)用來服務(wù)于電力企業(yè),就顯得尤為重要。
在當(dāng)今的編程術(shù)語里,分布式計(jì)算已經(jīng)成為很常見的詞,它將企業(yè)的業(yè)務(wù)數(shù)據(jù)和程序分布在網(wǎng)絡(luò)的不同物理位置上,通過調(diào)動(dòng)網(wǎng)絡(luò)上多臺(tái)計(jì)算機(jī)的處理能力,發(fā)揮遠(yuǎn)程調(diào)用數(shù)據(jù)的功能。
遠(yuǎn)程方法調(diào)用(Remote Method Invocation ,RMI),可以在不同的Java虛擬機(jī)(JVM)之間實(shí)現(xiàn)對(duì)象與對(duì)象的通信。JVM可以位于相同或不同計(jì)算機(jī)上,在多個(gè)JVM中,一個(gè)JVM可以調(diào)用存儲(chǔ)在其它JVM的對(duì)象的方法。
本文主要介紹RMI的特點(diǎn),分析應(yīng)用RMI進(jìn)行企業(yè)分布式計(jì)算的原理,以及利用RMI實(shí)現(xiàn)基于Java的企業(yè)分布式應(yīng)用的具體步驟。
遠(yuǎn)程方法調(diào)用(RMI)的特點(diǎn)
1、TCP編程的缺點(diǎn)
由于Java編程語言設(shè)計(jì)之初就是面向?qū)ο蠛椭С志W(wǎng)絡(luò)的,因此,基于對(duì)象的RMI機(jī)制已經(jīng)內(nèi)置在Java平臺(tái)中。
我們經(jīng)常會(huì)在網(wǎng)絡(luò)開發(fā)中使用TCP/IP編程,這樣,自然而然地就會(huì)涉及到Socket(套接字)編程。但是,使用Socket編程需要大量重復(fù)編碼,在復(fù)雜分布式操作時(shí)顯得非常麻煩,而且易于出錯(cuò)。因此,如何快速、高效、安全、可擴(kuò)展地進(jìn)行網(wǎng)絡(luò)分布式計(jì)算,是開發(fā)者們一貫追求和倡導(dǎo)的主題。直到RMI的出現(xiàn),這種繁雜、低效的開發(fā)情況才有很大改觀。
2、RMI編程的特點(diǎn)
當(dāng)我們利用對(duì)象序列化在網(wǎng)絡(luò)上分配對(duì)象時(shí),RMI提供了非Java平臺(tái)無法匹敵的獨(dú)特而強(qiáng)大的分布式計(jì)算模型,RMI主要有以下特點(diǎn):
客戶機(jī)可以向本地方法一樣調(diào)用遠(yuǎn)程服務(wù)器上的方法;
可以根據(jù)接口指定客戶機(jī)/服務(wù)器編程合約;
可以從服務(wù)器對(duì)象缺省二進(jìn)制類文件,自動(dòng)生成調(diào)動(dòng)/反調(diào)動(dòng)代碼;
將Java編程模型擴(kuò)展到機(jī)器邊界(和Java虛擬機(jī)(JVM)邊界之外),不需要任何特殊語法;
還可以和一個(gè)遠(yuǎn)程方法調(diào)用中的數(shù)據(jù)同時(shí)傳輸行為(代碼)。
盡管RMI不是唯一的企業(yè)級(jí)遠(yuǎn)程對(duì)象訪問方案,但它卻是最容易實(shí)現(xiàn)的。
3、RMI與CORBA
作為分布式應(yīng)用程序框架的規(guī)范,COBRA首當(dāng)其沖,它是由對(duì)象管理組織(OMG)開發(fā)的。與CORBA不同的是,CORBA能夠利用不同編程語言(例如C/C++、Basic等)開發(fā)實(shí)現(xiàn)分布式應(yīng)用,而RMI是一種純Java解決方案。在RMI中,程序的所有部分都由Java語言編寫,這樣,開發(fā)出來的程序完全符合Java規(guī)范,便于實(shí)現(xiàn)跨平臺(tái)訪問、擴(kuò)展和移植。按照筆者所在西北電力建設(shè)集團(tuán)公司的情況看,服務(wù)器操作系統(tǒng)主要有Linux和Windows2000 Server,分別存在于公司和部門當(dāng)中,它們是不同的系統(tǒng)平臺(tái);同時(shí),公司下屬各個(gè)工程項(xiàng)目部又距離很遠(yuǎn),近的幾十公里,遠(yuǎn)則達(dá)到上千公里甚至位于國外,因此跨平臺(tái)和遠(yuǎn)程訪問這兩大功能在開發(fā)企業(yè)應(yīng)用系統(tǒng)時(shí)就必須考慮,而RMI恰恰能夠用它的自身特點(diǎn)來滿足編程需要。
RMI基本體系結(jié)構(gòu)簡(jiǎn)介
RMI通過TCP/IP在內(nèi)部使用Socket,象其名稱暗示的那樣,它能夠幫助我們查找并執(zhí)行遠(yuǎn)程對(duì)象的方法。RMI的目的是讓位于不同JVM中的對(duì)象,在外觀及行為上都像是本地的對(duì)象。
通常,我們把調(diào)用這種遠(yuǎn)程對(duì)象的JVM,稱為客戶機(jī);而把包括這種遠(yuǎn)程對(duì)象的JVM,稱為服務(wù)器。
盡管對(duì)一個(gè)遠(yuǎn)程對(duì)象的引用和獲得對(duì)本地對(duì)象的引用有所不同,但我們可以把遠(yuǎn)程對(duì)象像本地對(duì)象一樣使用。應(yīng)用程序并不知道一個(gè)對(duì)象是遠(yuǎn)程的還是本地的。實(shí)際上,遠(yuǎn)程對(duì)象上被調(diào)用的方法與本地對(duì)象上調(diào)用的方法,具有相同的語法結(jié)構(gòu)。
作為RMI的底層(會(huì)包含復(fù)雜的Socket操作),它會(huì)自動(dòng)截獲方法調(diào)用,找到遠(yuǎn)程對(duì)象,然后處理遠(yuǎn)程請(qǐng)求。筆者認(rèn)為,RMI設(shè)計(jì)的重要之處,就在于不但在設(shè)計(jì)上實(shí)現(xiàn)了遠(yuǎn)程訪問功能,而且實(shí)現(xiàn)了設(shè)計(jì)的透明性。
RMI的基本體系結(jié)構(gòu),概括起來說,由三個(gè)抽象層組成:
1、存根/框架層(Stubs/Skeletons Layer)
RMI為我們引入了兩種特殊類型的對(duì)象,稱為存根(Stub)和框架(Skeleton),它們組成了RMI的第一層。
在遠(yuǎn)程通信的時(shí)候,要利用TCP/IP協(xié)議,做很多底層數(shù)據(jù)的打包傳輸。運(yùn)用Java技術(shù),我們先要把數(shù)據(jù)或者對(duì)象轉(zhuǎn)換成字節(jié)流(byte stream),便于網(wǎng)絡(luò)傳輸,這個(gè)過程叫匯集(marshaling);當(dāng)收到遠(yuǎn)程傳來的字節(jié)流后,我們要把流信息轉(zhuǎn)換成對(duì)象或者數(shù)據(jù),這個(gè)過程叫解讀(unmarshaling),它與匯集剛好相反。
Stub和Skeleton層位于實(shí)際應(yīng)用程序之下,建立在Proxy(代理)設(shè)計(jì)方案之上。Stub類的作用是遠(yuǎn)程服務(wù)器實(shí)現(xiàn)的代理的角色,Stub是客戶方對(duì)象;Skeleton類用于幫助對(duì)象通過RMI鏈接與Stub通信,它從鏈路中讀取方法調(diào)用的參數(shù),向遠(yuǎn)程服務(wù)實(shí)現(xiàn)對(duì)象進(jìn)行調(diào)用,接受返回值,然后再把返回值寫回到Stub。
2、遠(yuǎn)程引用層(Remote Reference Layer)
遠(yuǎn)程引用層定義和支持著RMI連接的調(diào)用語義(semantics)。
RMI進(jìn)行遠(yuǎn)程訪問要用到JRMP(Java Remote Method Protocol,即Java遠(yuǎn)程方法協(xié)議),這一層提供專用于JRMP的RemoteRef對(duì)象,它位于java.rmi.server包內(nèi),代表著遠(yuǎn)程對(duì)象的一個(gè)句柄。RemoteRef使用遠(yuǎn)程引用來執(zhí)行遠(yuǎn)程對(duì)象的一個(gè)遠(yuǎn)程方法調(diào)用。
3、傳輸層(Transport Layer)
傳輸層在JVM之間建立基于流的網(wǎng)絡(luò)連接,并且負(fù)責(zé)設(shè)置和管理這些連接。這時(shí)候,RMI使用一種線級(jí)(wire-level)協(xié)議進(jìn)行基于TCP/IP的連接,該協(xié)議就是Java遠(yuǎn)程方法協(xié)議(JRMP,即Java Remote Method Protocol)。
在JDK版本1.2開始,JRMP不再需要Skeleton,而是使用reflection來建立與遠(yuǎn)程服務(wù)的連接。為了生成Stub,我們須用rmic。
當(dāng)前的RMI實(shí)現(xiàn)中,傳輸層建立在TCP/IP基礎(chǔ)上,設(shè)計(jì)用于在客戶和服務(wù)器之間建立一條連接(即使聯(lián)網(wǎng)有障礙)。
開發(fā)的基本步驟
我們使用RMI編寫Client/Server模式(客戶/服務(wù)器)應(yīng)用程序,包括6個(gè)基本步驟:
1) 定義遠(yuǎn)程接口
2) 實(shí)現(xiàn)遠(yuǎn)程接口
3) 準(zhǔn)備遠(yuǎn)程調(diào)用的服務(wù)器對(duì)象
4) 生成殘根Stub(客戶代理)和框架Skeleton(服務(wù)器實(shí)體)
5) 用rmiregistry找到遠(yuǎn)程對(duì)象
6) 運(yùn)行測(cè)試RMI分布式應(yīng)用
開發(fā)企業(yè)信息發(fā)布系統(tǒng)實(shí)例
在開發(fā)RMI進(jìn)行分布式訪問之前,需要將各項(xiàng)功能模塊化,即把實(shí)際應(yīng)用抽象成符合Java規(guī)范的類和接口模型,使這些類和接口之間互相協(xié)作,能實(shí)現(xiàn)各自獨(dú)立的功能,最后,可以把它們組合成統(tǒng)一的網(wǎng)絡(luò)分布式系統(tǒng)。
現(xiàn)在,我們就以開發(fā)公司信息發(fā)布系統(tǒng)為例,把主模塊(主要的類文件)的名稱暫定為InfoDistributeService(信息發(fā)布服務(wù)),為了保持應(yīng)用開發(fā)的數(shù)據(jù)一致性和清晰度,接下來涉及的其它模塊命名也將以這個(gè)模塊命名為基準(zhǔn)。
1、定義遠(yuǎn)程接口
Java RMI運(yùn)行環(huán)境要求任何可以遠(yuǎn)程調(diào)用的方法必須放在遠(yuǎn)程接口中。
該遠(yuǎn)程接口用來擴(kuò)展java.rmi.Remote接口,在Java API中,可以發(fā)現(xiàn)它沒有任何方法,只是個(gè)標(biāo)志性接口,這樣,可以讓Java運(yùn)行環(huán)境(JRE)認(rèn)識(shí)每個(gè)接口的特殊屬性,以便能夠遠(yuǎn)程訪問。
因此,按照信息發(fā)布服務(wù)的命名(InfoDistributeService),首先須將InfoDistributeRemote定義為遠(yuǎn)程接口,同時(shí)僅放入一個(gè)供測(cè)試的方法 getRemoteInfo()來實(shí)現(xiàn)編碼,將所有模塊至于新建的enterprise.distribute包中,代碼如下:
// -----------InfoDistributeRemote.java-------------------
package enterprise. distribute;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface InfoDistributeRemote extends Remote{
public String getRemoteInfo() throws RemoteException;
}
2、實(shí)現(xiàn)遠(yuǎn)程接口
這是一個(gè)實(shí)現(xiàn)遠(yuǎn)程對(duì)象的類。如果實(shí)現(xiàn)了遠(yuǎn)程接口,就能夠覆蓋(override)該對(duì)象中的所有方法,因此,遠(yuǎn)程對(duì)象的實(shí)現(xiàn)類將真正包含我們希望導(dǎo)出的方法的代碼。
在遠(yuǎn)程信息發(fā)布系統(tǒng)中,我們至少實(shí)現(xiàn)一個(gè)遠(yuǎn)程接口的對(duì)象,它就是遠(yuǎn)程可訪問的對(duì)象。這里,InfoDistributeService類可以為我們生成遠(yuǎn)程可訪問對(duì)象的實(shí)例:
// -----------InfoDistributeService.java------------------
package enterprise. distribute;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class InfoDistributeService
extends UnicastRemoteObject implements InfoDistributeRemote{
public InfoDistributeService() throws RemoteException{
super();
}
// The return value of the method only for testing...
public String getRemoteInfo(){
return "Hello! I am a remote object.";
}
}
InfoDistributeService類實(shí)現(xiàn)遠(yuǎn)程接口InfoDistributeRemote,并繼承java.rmi.server.UnicastRemoteObject。由于符合InfoDistributeRemote接口,因此該類除構(gòu)造方法之外,還應(yīng)有g(shù)etRemoteInfo()方法,而且必須將該方法實(shí)現(xiàn)。
同時(shí)我們注意到,getRemoteInfo()方法拋出了java.rmi.RemoteException異常。由于遠(yuǎn)程方法調(diào)用過程中,要進(jìn)行很多的低級(jí)網(wǎng)絡(luò)操作,因此網(wǎng)絡(luò)錯(cuò)誤可能在調(diào)用過程中隨時(shí)發(fā)生,這樣,遠(yuǎn)程接口中的每個(gè)方法(盡管這里只有一個(gè)getRemoteInfo()方法)都必須拋出RemoteException異常,而且,java.rmi.RemoteException都要在代碼中顯式處理,即將所有RMI活動(dòng)涉及的代碼都要放在try-catch塊中。
3、準(zhǔn)備供遠(yuǎn)程調(diào)用的服務(wù)器對(duì)象
這是一個(gè)作為服務(wù)器使用的類,它是相對(duì)于要訪問遠(yuǎn)程方法的客戶端而言的。它存儲(chǔ)著綁定的字符串和對(duì)象。
將遠(yuǎn)程對(duì)象設(shè)置成接受遠(yuǎn)程調(diào)用就像啟動(dòng)了偵聽ServerSocket對(duì)象的socket服務(wù)器。事實(shí)上在使用RMI時(shí),TCP/IP協(xié)議的傳輸方式,在幕后發(fā)生了很多底層網(wǎng)絡(luò)操作,但是此刻,用戶不需要知道這些細(xì)節(jié),只需要逐步導(dǎo)出遠(yuǎn)程對(duì)象:
在Java開發(fā)工具的較新版本JDK 1.4中,可以選擇java.rmi.UnicastRemoteObject或者java.rmi.Activation.Activatable。其中,更多用到的是UnicastRemoteObject,因?yàn)樗櫭剂x,就是在客戶機(jī)與服務(wù)器對(duì)象實(shí)例之間建立一對(duì)一連接。
4、生成Stub和Skeleton
由RMI生成的調(diào)動(dòng)與反調(diào)動(dòng)的遠(yuǎn)程調(diào)動(dòng)代碼也和Java的其它代碼一樣,都包含在后綴是.class的文件中。
運(yùn)用RMI之后,在客戶機(jī)上生成的調(diào)動(dòng)參數(shù)和反調(diào)動(dòng)返回值的代碼稱為殘根(Stub),服務(wù)器上生成的反調(diào)動(dòng)參數(shù)和進(jìn)行實(shí)際方法調(diào)用調(diào)動(dòng)返回值的代碼稱為框架(Skeleton)。
可以使用RMI自帶的命令行工具rmic(即RMI Compiler),先掃描遠(yuǎn)程對(duì)象的.class文件,隨之生成殘根與框架代碼。工具rmic的原理
5、遠(yuǎn)程客戶端:這是一個(gè)幫助我們?cè)L問遠(yuǎn)程方法提供幫助的類,它也是最終用戶。我們將使用查找和調(diào)用遠(yuǎn)程方法的方法在該類中調(diào)用遠(yuǎn)程方法。
典型的rmic調(diào)用如下(在當(dāng)前目錄): 我們有了遠(yuǎn)程接口和實(shí)現(xiàn),就可以用rmic對(duì)類進(jìn)行編譯,生成Stub和Skeleton,在命令行窗口中使用以下代碼行:
// compile all java source files
javac enterprisedistribute*.java
// make stub and skeleton code
rmic enterprise.distribute.InfoDistributeService
運(yùn)行完畢后,在當(dāng)前目錄生成下列文件(即調(diào)動(dòng)代碼):
InfoDistributeService_Stub.class
InfoDistributeService_Skel.class
5、用rmiregistry找到遠(yuǎn)程對(duì)象
導(dǎo)出服務(wù)器方的對(duì)象之后,就可以遠(yuǎn)程訪問,但客戶機(jī)還要設(shè)法與這些遠(yuǎn)程對(duì)象取得聯(lián)系。
由于分布式應(yīng)用程序可能涉及許多不同機(jī)器,因此通信的所有機(jī)器對(duì)之間需要建立初始連接,換句話說,就是要設(shè)法找到初始遠(yuǎn)程對(duì)象,這項(xiàng)工作通過rmiregistry命令執(zhí)行。
JDK開發(fā)工具提供了實(shí)用程序RMI Registry,用來維護(hù)文本名和遠(yuǎn)程對(duì)象之間的映射,可以進(jìn)行遠(yuǎn)程訪問。
在客戶機(jī)方,RMI注冊(cè)表可以通過同一java.rmi.Naming類的lookup()靜態(tài)方法用程序訪問。例如,遠(yuǎn)程主機(jī)為iServer,遠(yuǎn)程對(duì)象實(shí)例為InfoDistributeService實(shí)例,遠(yuǎn)程端口號(hào)為5678,則客戶機(jī)如果查找遠(yuǎn)程主機(jī)iServer中的遠(yuǎn)程InfoDistributeService實(shí)例,那么引用實(shí)例時(shí)須使用遠(yuǎn)程接口InfoDistributeRemote,代碼如下:
InfoDistributeRemote iServer=( InfoDistributeRemote)Naming.lookup("rmi://iServer:5678/InfoDistributeService");
在服務(wù)器方,導(dǎo)出的遠(yuǎn)程對(duì)象可以通過java.rmi.Naming類在本地注冊(cè)rmiregistry的運(yùn)行實(shí)例。例如,用rebind()方法將iService中的InfoDistributeService的實(shí)例與名稱InfoDistributeService相關(guān)聯(lián)。
InfoDistributeService iService=new InfoDistributeService();
Naming.rebind("/ InfoDistributeService",iService);
綜上所述,InfoDistributeRemote是個(gè)Java接口,因此iServer實(shí)際上是實(shí)現(xiàn)InfoDistributeRemote接口的本地對(duì)象實(shí)例,它不在遠(yuǎn)程,而是遠(yuǎn)程InfoDistributeService的本地表示。也就是說,它是由前述rmic工具自動(dòng)生成的殘根碼InfoDistributeService_Stub.class的本地實(shí)例。
客戶機(jī)實(shí)現(xiàn)通過iServer變量維護(hù)遠(yuǎn)程對(duì)象的調(diào)用。事實(shí)上,iServer引用變量是實(shí)現(xiàn)InfoDistribute接口的對(duì)象的本地引用,該對(duì)象是InfoDistributeService殘根實(shí)現(xiàn)。這個(gè)殘根和服務(wù)器方的框架一起通過InfoDistributeRemote接口調(diào)動(dòng)/反調(diào)動(dòng)所有遠(yuǎn)程調(diào)用。
當(dāng)我們把InfoDistributeService看成是實(shí)現(xiàn)InfoDistributeRemote接口的本地實(shí)例的時(shí)候,殘根代碼只在幕后進(jìn)行工作,而實(shí)現(xiàn)這一切則變得非常透明。
由上述原理,可以進(jìn)一步設(shè)計(jì)完善客戶機(jī)和服務(wù)器代碼,進(jìn)而編寫出完整的應(yīng)用程序。
6、運(yùn)行測(cè)試RMI分布式應(yīng)用
在確認(rèn)已經(jīng)設(shè)計(jì)好必須的幾大類模塊后,我們開始按以下步驟,運(yùn)行并測(cè)試該信息發(fā)布系統(tǒng)的基本功能(即僅僅實(shí)現(xiàn)遠(yuǎn)程接口中聲明的getRemoteInfo()方法)。
在前面定義的包enterprise.distribute中,執(zhí)行javac命令編譯后綴為.java的源文件。
javac enterprise/distribute/*.java
接著,用RMIC工具生成殘根與框架。
rmic enterprise.distribute.InfoDistributeService
編譯之后,需要確定客戶機(jī)與服務(wù)器發(fā)行版本的內(nèi)容。因此,需用jar命令,將客戶機(jī)與服務(wù)器發(fā)行版本包裝成 .jar文件。 其中,包裝服務(wù)器的文件命令如下:
jar cvf InfoDistributeService.jar
enterprisedistributeInfoDistributeService.class
enterprisedistributeInfoDistributeRemote.class
enterprisedistributeInfoDistributeService_Stub.class
enterprisedistributeInfoDistributeService_Skel.class
同樣,包裝客戶機(jī)的類似于以上命令。
運(yùn)行RMI應(yīng)用程序
完成了第一階段的所有RMI試驗(yàn),然后運(yùn)行信息發(fā)布應(yīng)用程序。按照J(rèn)ava規(guī)范,需要依次啟動(dòng)下列項(xiàng)目:
啟動(dòng)RMIRegistry
在代碼目錄中用以下命令啟動(dòng)rmiregistry實(shí)例,使之在控制臺(tái)開始運(yùn)行。
start rmiregistry
啟動(dòng)服務(wù)器
直接啟動(dòng)服務(wù)器,生成InfoDistributeService遠(yuǎn)程對(duì)象的實(shí)例,并向注冊(cè)表注冊(cè)。
start java -classpath InfoDistributeService.jar
enterprise.distribute.InfoDistributeService
啟動(dòng)客戶機(jī)
最后,用java -classpath RemoteClient.jar 命令啟動(dòng)客戶機(jī),然后通過rmiregistry找到遠(yuǎn)程信息發(fā)布服務(wù),再通過遠(yuǎn)程調(diào)用得到所需要的遠(yuǎn)程信息。
結(jié)論
本文簡(jiǎn)要闡述了Java RMI的特點(diǎn),以及用RMI開發(fā)企業(yè)分布式應(yīng)用的主要步驟。以遠(yuǎn)程信息發(fā)布系統(tǒng)為例,簡(jiǎn)要地說明了遠(yuǎn)程對(duì)象訪問、遠(yuǎn)程方法調(diào)用在信息發(fā)布時(shí)的原理和實(shí)現(xiàn)過程。
為了開發(fā)出更符合實(shí)際的企業(yè)分布式應(yīng)用,RMI還可以結(jié)合對(duì)象序列化實(shí)現(xiàn)更加強(qiáng)大的功能,為我們開發(fā)更加靈活、高效的網(wǎng)絡(luò)分布式應(yīng)用系統(tǒng)提供方便。