首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2EE

深入解析 RMI 規範第二章:Java 分布式對象模型核心概念

     編輯:J2EE

Java 分布式對象模型概述

RMI(Remote Method Invocation)應用程序通常由兩個獨立程序構成:服務器程序與客戶機程序。服務器負責創建多個遠程對象並將其註冊供查找,隨後等待客戶機調用;客戶機則獲取遠程對象引用並調用其方法。RMI 為雙方通訊與信息傳遞提供了透明機制,這類應用被稱為分布式對象應用程序。

分布式對象應用的三大核心需求

  • 定位遠程對象:可通過 RMI 命名工具 rmiregistry 註冊,或在常規操作中傳遞/返回引用。
  • 與遠程對象通訊:RMI 封裝了網絡細節,遠程調用語法與本地方法調用一致。
  • 加載類字節碼:支持傳遞純 Java 對象,RMI 提供機制加載對象代碼並傳輸數據,兼容 HTTP、FTP、file 等 URL 協議。

術語定義:什麼是遠程對象?

在 Java 分布式對象模型中,Remote Object 指其方法可從其他 Java 虛擬機(可能位於不同主機)調用的對象。此類對象由一個或多個 Remote Interface(聲明遠程方法的 Java 接口)描述。遠程方法調用 (RMI) 即調用遠程對象上遠程接口方法的動作,其語法與本地調用完全相同。

分布式模型與本地模型的異同

相似點

  • 遠程對象引用可在任何方法調用中作為參數傳遞或返回結果。
  • 可強制轉換為任何受支持的遠程接口。
  • 可用 instanceof 檢測遠程對象支持的接口。

關鍵差異

  • 客戶機僅與遠程接口交互,不與實現類交互。
  • 非遠程參數/返回值採用按值傳遞(複製)而非引用傳遞,因引用僅在單個 JVM 有效。
  • 遠程對象以引用方式傳遞(傳遞 stub),而非複製實現。
  • java.lang.Object 某些方法語義專門針對遠程對象調整。
  • 遠程調用失敗模式更複雜,客戶機必須處理額外異常(如 RemoteException)。

RMI 核心接口與類詳解

1. java.rmi.Remote 接口——遠程接口的標記

所有遠程接口必須直接或間接擴展 java.rmi.Remote。它是一個不包含方法的標記接口:

public interface Remote

遠程方法聲明要求:

  • throws 子句必須包含 java.rmi.RemoteException 或其超類(如 IOException、Exception)。
  • 參數/返回值中的遠程對象必須聲明為遠程接口類型,而非實現類。

示例:銀行賬戶遠程接口

public interface BankAccount extends java.rmi.Remote {
    public void deposit(float amount) throws java.rmi.RemoteException;
    public void withdraw(float amount) throws OverdrawnException, java.rmi.RemoteException;
    public float getBalance() throws java.rmi.RemoteException;
}

示例:擴展非遠程接口的有效遠程接口

public interface Alpha {
    public final String okay = "constants are okay too";
    public Object foo(Object obj) throws java.rmi.RemoteException;
    public void bar() throws java.io.IOException;
    public int baz() throws java.lang.Exception;
}
public interface Beta extends Alpha, java.rmi.Remote {
    public void ping() throws java.rmi.RemoteException;
}

2. RemoteException 類——遠程調用失敗的根異常

java.rmi.RemoteException 是 RMI 運行時拋出的異常超類,屬於已檢查異常(非 RuntimeException),調用者必須處理。常見失敗原因:

  • 通訊失敗(服務器不可達、連接被拒/關閉)
  • 參數/返回值序列化或讀取失敗
  • 協議錯誤

3. RemoteObject 及其子類——服務器端實現基石

  • RemoteObject:實現 hashCode、equals、toString 的遠程語義。
  • RemoteServer:服務器實現的通用超類。
  • UnicastRemoteObject:單點傳輸遠程對象,引用僅在服務器進程存活期內有效。
  • Activatable:可激活遠程對象,按需啟動、閒置關閉。

實現遠程接口的最佳實踐

實現類通常擴展 UnicastRemoteObject 以繼承遠程行為,可實現多個遠程接口,也可定義僅本地可用的方法。構造函數需拋出 RemoteException。

package mypackage;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class BankAccountImpl extends UnicastRemoteObject implements BankAccount {
    private float balance = 0.0f;

    public BankAccountImpl(float initialBalance) throws RemoteException {
        balance = initialBalance;
    }

    public void deposit(float amount) throws RemoteException { /* ... */ }
    public void withdraw(float amount) throws OverdrawnException, RemoteException { /* ... */ }
    public float getBalance() throws RemoteException { /* ... */ }
}

遠程方法調用中的參數傳遞機制

參數/返回值可為任意可序列化 Java 對象:基本類型、遠程對象、實現 Serializable 的非遠程對象。本地不可用的類可通過 RMI 動態下載。

傳遞規則總覽

對象類型傳遞方式說明
非遠程對象按值傳遞(序列化複製)調用前複製內容;返回時在調用端創建新對象
遠程對象按引用傳遞(傳遞 stub)僅傳遞實現遠程接口的 stub

引用完整性保證

單次遠程調用中,若兩個引用指向發送端同一對象,接收端將指向同一副本。RMI 通過單一 ObjectOutputStream 寫入參數保證此特性。

類註解與動態加載

對象跨 JVM 傳輸時,RMI 在調用流中用 codebase URL 註解類描述符,接收端可由此下載類定義。ObjectOutputStream 子類覆蓋 replaceObject(遠程對象替換為 stub)與 annotateClass(註解 codebase)。

定位遠程對象:命名服務

RMI 提供基於 URL 的簡單引導命名服務。java.rmi.Naming 類提供 bind、rebind、unbind、list 等方法,操作特定主機/端口上的名字-對象綁定。客戶機通過 JNDI 或 Naming 查找獲取遠程引用,隨後發起調用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved