📜  Java RMI(远程方法调用)(1)

📅  最后修改于: 2023-12-03 15:01:32.001000             🧑  作者: Mango

Java RMI(远程方法调用)

Java RMI,或称远程方法调用,是一种使得 Java 虚拟机 (JVM) 可以在分布式环境下相互交互的技术。它可以让一个 JVM 的对象以远程对象的形式,通过网络接口,在另一个 JVM 上呈现。对于分布式应用程序,Java RMI 成为了一种完美的选择。下面,我们将对 Java RMI 进一步介绍。

RMI核心概念
  • 远程接口 (Remote Interface)
  • 远程对象 (Remote Object)
  • RMI 注册表 (RMI Registry)
  • 客户端 (Client)
实现 Java RMI
远程接口 (Remote Interface)

每次我们调用对象的方法时,Java 虚拟机都会检查该方法在它的接口定义中是否存在。因此,如果希望将一个对象创建为远程对象,我们必须定义一个远程接口,并在该接口中定义将要由客户端调用的方法。

远程接口定义使用 Java 编程语言编写,在其中描述所有的远程方法:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface HelloInterface extends Remote {
    public String sayHello() throws RemoteException;
}
  • extends Remote 确定这个接口为远程接口。
  • RemoteException 指定这个接口可能会向远程调用端报告远程问题。
远程对象 (Remote Object)

Java RMI 在远程机器上创建的对象称作“远程对象”。这些远程对象存储在服务器上并且对不同的客户端都是可用的。客户端通过网络访问远程对象,并调用其方法。当定义一个远程接口时,我们需要将我们的对象实现为该接口的具体实现类。在这个实现类中我们可以编写想要远程调用的所有方法,这些方法都有如下的格式:

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

public class HelloImpl extends UnicastRemoteObject implements HelloInterface {

    public HelloImpl() throws RemoteException {
        super();
    }

    public String sayHello() throws RemoteException {
        return "Hello!";
    }
}
  • extends UnicastRemoteObject 确认该类是远程对象。
  • UnicastRemoteObject 是 Java RMI 中一个特殊的类,用于创建远程对象,需要抛出 RemoteException。
RMI 注册表 (RMI Registry)

在 Java RMI 中,RMI 注册表类似于命名服务。在远程机器上使用 RMI 注册表,以便客户端可以访问远程对象。客户端通过 RMI 注册表查找远程对象,然后在 JVM 中创建它的一个替身。

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Server {
    
    public static void main(String args[]) throws Exception {

        // 创建远程对象
        HelloImpl obj = new HelloImpl();

        // 启动注册表
        LocateRegistry.createRegistry(1099);

        // 注册对象
        Naming.rebind("rmi://localhost/HelloServer", obj);

        System.out.println("HelloServer bound in registry");
    }
}
  • createRegistry(1099) 创建 RMI 注册表,该表会在 1099 上监听,以便客户端可以查找它们需要的远程对象。
  • Naming.rebind("rmi://localhost/HelloServer", obj) 将远程对象注册到 RMI 注册表中的 '/HelloServer' 名称下。
客户端 (Client)

客户端通过 RMI 注册表查找远程对象,并在 JVM 中创建它的一个替身:

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
  
     public static void main(String args[]) throws Exception {
        
        // 获取注册表
        Registry registry = LocateRegistry.getRegistry("localhost");
        
        // 获取远程对象引用
        HelloInterface stub = (HelloInterface) registry.lookup("HelloServer");
        
        // 调用远程方法
        String response = stub.sayHello();
        System.out.println("response: " + response);
     }
}
  • getRegistry("localhost") 获取远程对象所连接的 RMI 注册表。
  • lookup("HelloServer") 查找注册表中 '/HelloServer' 的远程对象引用。
  • (HelloInterface) 强制转换远程对象引用为远程接口类型。
总结

Java RMI 可以让我们在分布式应用程序中使用 Java 对象。我们可以将一个类实现为远程对象,并通过 RMI 注册表将其注册,在多个 JVM 中进行交互。但是,它不是一个完整的分布式系统,不能作为编写完整分布式应用程序的唯一技术。