1. 程式人生 > >JAVA RMI 文件中文(二)

JAVA RMI 文件中文(二)

2.6 遠端方法呼叫時的引數傳遞

一個遠端物件只要可以序列化就可以是方法引數或是返回值。這就包括了基礎物件、遠端物件和實現了java.io.Serializable的非遠端物件。更多關於如何序列化類的資訊科一參考 “Java Object Serialization Specification”。這些引數或者返回值不是本地的,它們是通過RMI系統動態下載的。更多細節檢視Dynamic Class Loading

2.6.1 傳遞非遠端物件

一個非遠端物件,無論是作為引數還是返回值,它都是通過複製來傳遞的,也就是通過java的序列化機制序列化後得到的。

所以,在方法呼叫過程中,當一個遠端物件作為引數或者返回值被傳遞時,這個非遠端物件的內容會在方法呼叫前被複制。

當呼叫遠端方法返回一個非遠端物件時,本地虛擬機器就會建立一個新的物件。

2.6.2 傳遞遠端物件

當傳遞一個遠端物件時,實際傳遞的是這個物件的存根(stub)。
沒有暴露的遠端物件不會被存根例項替代。遠端物件只有實現了遠端接口才可以作為引數被傳遞。

2.6.3 引用的完整性(Referential Integrity)

如果一個物件的兩個引用作為一個遠端方法的引數從一個虛擬機器傳遞到另一個虛擬機器,那麼這些引用在傳送物件的虛擬機器中指向的是同一個物件,它們在接收物件的虛擬機器中指向的是同一個物件的副本,RMI系統會在物件傳遞過程中保證引用的完整性。

2.6.4 類註釋(Class Annotation)

當一個物件通過方法呼叫,從一個虛擬機器傳遞到另一個虛擬機器時,RMI系統會通過URL來標識這個類,以便可以在接收端載入這個類。這個要求保證類會按需下載。
(這裡翻譯的感覺有點問題,下面是原文)

When an object is sent from one JVM to another in a remote method call, the RMI system annotates the class descriptor in the call stream with information (the URL) of the class so that the class can be loaded at the receiver. It is a requirement that classes be downloaded on demand during remote method invocation.

2.6.5 引數傳遞

在RMI呼叫中引數被寫到流中,該流是java.io.ObjectOutputStream的子類,這樣是為了可以將引數序列化到遠端呼叫虛擬機器中。ObjectOutputStream子類會重寫replaceObject方法,該方法用每一個暴露的遠端物件所對應的存根例項來替換他們。引數這些物件是通過ObjectOutputStreamwriteObject方法來寫入流中的。ObjectOutputStream會為每一個通過writeObject方法寫入流的物件呼叫replaceObject方法(包括寫入物件所引用的物件)。replaceObject方法返回結果如下:
1、如果這個物件實現了java.rmi.Remote而且這個物件在RMI執行時被匯出,那麼該方法返回這個物件的存根例項。如果這個物件實現了java.rmi.Remote,但是沒有在RMI執行時被匯出,那麼replaceObject方法返回該物件本身。對於遠端物件的存根,可以通過呼叫java.rmi.server.RemoteObjecttoStub方法獲得。
2、如果這個物件不是一個java.rmi.Remote的例項,那麼會簡單返回該物件。

RMI中ObjectOutputStream的子類也會實現annotateClass方法,該類會通過遠端類的位置來對類進行解釋說明,以便該類可以在接收端被下載。

因為引數寫入是通過一個單獨的ObjectOutputStream,所以同一個物件的引用在接收端會指向同一個物件的副本。在接收端,引數通過一個單獨的ObjectInputStream讀出來。

ObjectOutputStream的其他任何寫物件的行為(ObjectInputStream的讀取物件和它類似)都是在引數傳遞中維護的。比如說,在寫物件是會呼叫writeReplace方法,在讀物件的時候回撥用readResolve方法,這些方法都是由RMI引數的編排或者反編排流提供的。

返回值和異常的傳遞和上面講的引數傳遞類似。