Java RMI - UnicastRemoteObject:UnicastRemoteObject.exportObject() 和 extends UnicastRemoteObject 之间有什么区别?

2022-09-02 13:02:24

我正在准备考试,我有一个问题,我希望这里的某个人能回答我。

这是关于RMI和远程对象的。我想知道为什么这两种实现之间有这么大的差异。一个是扩展单播远程对象,而另一个是将对象导出为单播远程对象。

我真的不明白区别

接口:

public interface EchoI extends Remote {
   public String echo() throws RemoteException
}

这是服务器代码(版本 1):

public class EchoImpl extends UnicastRemoteObject implements EchoI {
    public EchoImpl {
        super();
    }

    public static void main (String[] args) {
        try {
            LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
            StoreHouse storehouseImpl = new StorehouseImpl();
            Naming.rebind("//localhost/StoreHouse.SERVICE_NAME", storehouseImpl);
            System.out.println("Server ready");
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
    }

    public String echo() {
        return "echo";
    }
}

这将是版本2:

public class EchoImpl implements EchoI {
    public static void main (String[] args) {
        EchoI echoService = new EchoImpl();
        EchoI stub = (EchoI) UnicastRemoteObject.exportObject(echoService, 0);
        Registry registry = LocateRegistry.getRegistry();
        registry.bind("echoService", stub);
        ...
    }
}

我的问题是:这两者之间有什么区别?

在第一个版本中,注册表是显式创建的,此外,远程对象是在重新绑定中创建的?

我真的很好奇,为什么在第一个中我需要自己创建注册表,但不需要显式导出对象,只需使用重新绑定它。该对象之前是否已绑定到注册表,或者是否可以改用 bind?如果对象之前未绑定并且重新绑定被解除,会发生什么情况?Naming

在第二个版本中,注册表似乎已经创建。为什么绑定到命名与直接绑定到注册表相同?

这就是,我的想法:

  • 第一个类 direclty 实现接口 UnicastRemoteObject,这意味着在运行时创建注册表,并且对象自动导出到 RMI 注册表。
  • 由于对象已绑定到注册表,因此必须进行重新绑定而不是正常绑定。
  • 后者明确地做到了这一切。

答案 1

这里有两个问题。

  1. 您可以扩展或调用,这取决于您。第一个是简单和自动的;第二个意味着您可以扩展另一个类。UnicastRemoteObjectUnicastRemoteObject.exportObject().

  2. 您可以使用外部 RMI 注册表,也可以在服务器 JVM 中自行创建注册表。同样,你做什么取决于你,两种方式都有优势。

    这两个问题没有相互作用。

  3. 如果您还获得了 和 方法的“远程语义”的好处,使得所有存根看起来都与导出它们的远程对象相同,但这在客户端没有实际用途,实际上只是为了支持 RMI 实现本身。extend UnicastRemoteObjecthashCode()equals()


答案 2

java.rmi.server.UnicastRemoteObject用于使用 Java 远程方法协议 (JRMP) 导出远程对象并获取与远程对象通信的存根。

对于下面的构造函数和静态方法,将获得要导出的远程对象的存根...exportObject

在那里,您应该遵循Javadoc