如果所有組件都在同一臺(tái)計(jì)算機(jī)的同一個(gè)Java虛擬機(jī)的同一個(gè)堆空間上執(zhí)行是最簡單的,但實(shí)際中我們面對(duì)的往往不是如此單一的情況,如果用戶端只是個(gè)能夠執(zhí)行Java的裝置怎么辦?如果為了安全性的理由只能讓服務(wù)器上的程序存取數(shù)據(jù)庫怎么辦?
我們知道,大多數(shù)情況下,方法的調(diào)用都是發(fā)生在相同堆上的兩個(gè)對(duì)象之間,如果要調(diào)用不同機(jī)器上的對(duì)象的方法呢?
通常,我們從某一臺(tái)計(jì)算機(jī)上面取得另一臺(tái)計(jì)算機(jī)上的信息是通過socket的輸入/輸出流,打開另一臺(tái)計(jì)算機(jī)的socket連接,然后取得outputStream來寫入數(shù)據(jù).但如果要調(diào)用另一臺(tái)計(jì)算機(jī)上,另一個(gè)Java虛擬機(jī)上面的對(duì)象的方法你?我們當(dāng)然可以自己定義和設(shè)計(jì)通信協(xié)議來調(diào)用,然后通過Socket把執(zhí)行結(jié)果再傳回去,并且還能夠像是對(duì)本機(jī)的方法調(diào)用一樣,也就是說想要調(diào)用遠(yuǎn)程的對(duì)象(像是別的堆上的),卻又要像是一般的調(diào)用.
這就是RMI帶給我們的功能.
遠(yuǎn)程過程調(diào)用的設(shè)計(jì)
要?jiǎng)?chuàng)建出4種東西:服務(wù)器、客戶端、服務(wù)器輔助設(shè)施和客戶端輔助設(shè)施.
1.創(chuàng)建客戶端和服務(wù)端應(yīng)用程序,服務(wù)器應(yīng)用程序時(shí)個(gè)遠(yuǎn)程服務(wù),是個(gè)帶有客戶端會(huì)調(diào)用的方法的對(duì)象
2.創(chuàng)建客戶端和服務(wù)器端的輔助設(shè)施(helper)他們會(huì)處理所有客戶端和服務(wù)器的底層網(wǎng)絡(luò)輸入/輸出細(xì)節(jié),讓客戶端和程序好像在處理本地調(diào)用一樣.
輔助設(shè)施的任務(wù)輔助設(shè)施是個(gè)在實(shí)際上執(zhí)行通信的對(duì)象,他們會(huì)讓客戶端感覺上好像是在調(diào)用本機(jī)對(duì)象,客戶端對(duì)象看起來像是在調(diào)用遠(yuǎn)程的方法,但實(shí)際上它只是在調(diào)用本地處理Socket和串流細(xì)節(jié)的代理.在服務(wù)器這端,服務(wù)器的輔助設(shè)施會(huì)通過socket連接來自客戶端設(shè)施的要求,解析打包送來的信息,然后調(diào)用真正的服務(wù),因此對(duì)服務(wù)對(duì)象來說此調(diào)用來自本地.服務(wù)的輔助設(shè)施取得返回值之后就把它包裝然后送回去(通過socket的輸出串流)給客戶端的輔助設(shè)施.客戶端的輔助設(shè)施會(huì)解開這些信息傳輸給客戶端的對(duì)象
調(diào)用方法的過程
1.客戶端對(duì)象對(duì)輔助設(shè)施對(duì)象調(diào)用doBigThing()
2.客戶端輔助設(shè)施把調(diào)用信息打包通過網(wǎng)絡(luò)送到服務(wù)器的輔助設(shè)施
3.服務(wù)端的輔助設(shè)施解開來自客戶端輔助設(shè)施的信息,并以此調(diào)用真正的服務(wù).
這個(gè)過程的描述圖如下:
Java RMI提供客戶端和服務(wù)器端的輔助設(shè)施對(duì)象
在Java中,RMI已經(jīng)幫我們創(chuàng)建好客戶端和服務(wù)器端的輔助設(shè)施,它也知道如何讓客戶端輔助設(shè)施看起來像是真正的服務(wù),也就是說,RMI知道如何提供相同的方法給客戶端調(diào)用.
此外,RMI有提供執(zhí)行期所需全部的基礎(chǔ)設(shè)施,包括服務(wù)的查詢以及讓客戶端能夠找到與取得客戶端的輔助設(shè)施(真正的服務(wù)代理人).
使用RMI時(shí),無需編寫任何網(wǎng)絡(luò)或輸入/輸出的程序,客戶端對(duì)遠(yuǎn)程方法的調(diào)用就跟對(duì)同一個(gè)Java虛擬機(jī)上的方法調(diào)用是一樣的.
一般調(diào)用和RMI調(diào)用有一點(diǎn)不同,雖然對(duì)客戶端來說,此方法調(diào)用看起來像是本地的,但是客戶端輔助設(shè)施會(huì)通過網(wǎng)絡(luò)發(fā)出調(diào)用,此調(diào)用最終還是會(huì)涉及到socket和串流,一開始是本機(jī)調(diào)用,代理會(huì)把它轉(zhuǎn)成遠(yuǎn)程的.中間的信息是如何從Java虛擬機(jī)送到Java虛擬機(jī)要看輔助設(shè)施對(duì)象所用的協(xié)議而定.
使用RMI時(shí),必須要決定協(xié)議:JRMP或IIOP,JRMP是RMI原生的協(xié)議,它是為Java間的遠(yuǎn)程調(diào)用而設(shè)計(jì)的,另外一方面,IIOP是為了CORBA而產(chǎn)生的,它讓我們能夠調(diào)用Java對(duì)象或其它類型的遠(yuǎn)程方法,CORBA通常比RMI麻煩,因?yàn)槿魞啥瞬蝗际?/SPAN>Java的話,就會(huì)產(chǎn)生一堆可怕的轉(zhuǎn)譯和交談操作.
我們只關(guān)心Java對(duì)Java的操作,所以會(huì)使用相當(dāng)簡易的RMI.
在RMI中,客戶端的輔助設(shè)施稱為stub,而服務(wù)器端的輔助設(shè)施稱為skeleton.
如何創(chuàng)建遠(yuǎn)程服務(wù)
1.創(chuàng)建Remote接口
遠(yuǎn)程的接口定義了客戶端可以遠(yuǎn)程調(diào)用的方法,它是個(gè)作為服務(wù)的多態(tài)化類.stub和服務(wù)都會(huì)實(shí)現(xiàn)此接口
2.實(shí)現(xiàn)Remote接口
這個(gè)是真正執(zhí)行的類,它實(shí)現(xiàn)出定義在該接口上的方法,它是客戶端會(huì)調(diào)用的對(duì)象
3.用rmic產(chǎn)生stub和skeleton
客戶端和服務(wù)器都有helper,我們無需創(chuàng)建這些類或產(chǎn)生這些類的源代碼,這都會(huì)在執(zhí)行JDK所附的rmic工具時(shí)自動(dòng)地處理掉
4.啟動(dòng)RMI registry (rmiregistry)
rmiregistry就像電話薄,用戶會(huì)從此處取得代理(客戶端的stub/helper對(duì)象)
5.啟動(dòng)遠(yuǎn)程服務(wù)
必須讓服務(wù)對(duì)象開始執(zhí)行,實(shí)現(xiàn)服務(wù)的類會(huì)起始服務(wù)的實(shí)例并向RMI Registry注冊(cè),要有注冊(cè)后才能對(duì)用戶服務(wù).
服務(wù)端代碼
定義接口 /**
import java.rmi.Remote;
import java.rmi.RemoteException;
*
* MyRemote.java
*
* 功 能: TODO
* 類 名: MyRemote.java
*
* ver
主站蜘蛛池模板:
湖州市|
涡阳县|
浮山县|
永修县|
连云港市|
拉萨市|
公安县|
沂南县|
永寿县|
浑源县|
股票|
景谷|
胶南市|
宁波市|
天水市|
象山县|
丰镇市|
清新县|
乌审旗|
宾川县|
建德市|
昌乐县|
阳山县|
仪陇县|
苍南县|
高要市|
拜城县|
锡林郭勒盟|
宁波市|
通州市|
陆河县|
尚义县|
鄂温|
嘉峪关市|
郎溪县|
麦盖提县|
舞阳县|
台北市|
宿松县|
阿拉善右旗|
新泰市|