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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2194935/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 04:37:40  来源:igfitidea点击:

Java RMI - UnicastRemoteObject: what is the difference between UnicastRemoteObject.exportObject() and extends UnicastRemoteObject?

javainterfaceexportrmi

提问by CatholicEvangelist

i'm preparing for an exam and I'm having a question that I hope someone here could answer me.

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

It's about RMI and remote objects. I wonder why there is so much difference between these two implementations. one is extending the UnicastRemoteObject whereas the other is exporting the object as an UnicastRemoteObject.

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

I don't really get the difference

我真的不明白

Interface:

界面:

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

This is the server code (version 1):

这是服务器代码(版本 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";
    }
}

and this would be version 2:

这将是第 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);
        ...
    }
}

My question is: what is the difference between these two?

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

In thefirst version the registry is explicitly created, furthermore the remote object is created within a rebind?

在第一个版本中,注册表是明确创建的,而且远程对象是在重新绑定中创建的?

I'm really curious, why in the first I need to create the registry myself but do not need to export the object explicitly and just rebind it using Naming. Is that object already bound to the registry before, or could I use bind instead? And what happens, if the object was not previously bound and a rebind is excecuted?

我真的很好奇,为什么首先我需要自己创建注册表但不需要显式导出对象而只需使用Naming. 该对象之前是否已经绑定到注册表,或者我可以改用绑定吗?如果对象先前未绑定并且执行重新绑定,会发生什么情况?

In the second version, the registry seems to be already created. Why is binding to naming the same as binding to an registry directly?

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

This is, what I think:

这是,我的想法:

  • the first class direclty implements the interface UnicastRemoteObject which means, that at runtime the registry is created and the object is automatically exported to the RMI registry.
  • as the object is already bound to the registry, a rebind instead of a normal bind must take place.
  • the latter does all this explicitly.
  • 第一类 direclty 实现接口 UnicastRemoteObject,这意味着在运行时创建注册表并将对象自动导出到 RMI 注册表。
  • 由于对象已经绑定到注册表,因此必须进行重新绑定而不是正常绑定。
  • 后者明确地完成了这一切。

采纳答案by stacker

java.rmi.server.UnicastRemoteObjectis used for exporting a remote object with Java Remote Method Protocol (JRMP) and obtaining a stub that communicates to the remote object.

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

For the constructors and static exportObjectmethods below, the stub for a remote object being exported is obtained ...

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

There you should follow the Javadoc

在那里你应该遵循Javadoc

回答by user207421

There are two questions here.

这里有两个问题。

  1. You can either extend UnicastRemoteObjector call UnicastRemoteObject.exportObject().Which you do is up to you. The first is simple and automatic; the second means you can extend another class.

  2. You can either use an external RMI Registry or create it yourself inside your server JVM. Again which you do is up to you, there are advantages both ways.

    These two questions have no interaction.

  3. If you extend UnicastRemoteObjectyou also get the benefit of 'remote semantics' for the hashCode()and equals()methods, such that all stubs appear to be identical to the remote object that exported them, but this is of no practical use on the client side, and is really only there to support the RMI implementation itself.

  1. 你可以扩展UnicastRemoteObject或调用UnicastRemoteObject.exportObject().你做什么取决于你。第一个是简单和自动的;第二种意味着你可以扩展另一个类。

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

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

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

回答by A Gilani

You can call the UnicastRemoteObject.exportObject()instead of extending the UnicastRemoteObjectin a scenario where you need to extend any other class. Overall effect is the same I think.

在需要扩展任何其他类的场景中,您可以调用UnicastRemoteObject.exportObject()而不是UnicastRemoteObject扩展 。整体效果和我想的一样。

See this

看到这个

回答by atjua

Firstly, binding & rebinding remote object using Namingclass and Registryclass is not relevant to scenarios of whether or not a class is extending UnicastRemoteObject. See herefor the differences.

首先,使用Naming类和Registry类绑定和重新绑定远程对象与类是否扩展的场景无关UnicastRemoteObject。请参阅此处了解差异。

Secondly, the difference between the class extending UnicastRemoteObjectis that if the object of that type is used as a stub, then you'll not need to call UnicastRemoteObject.exportObjectto obtain the stub anymore for binding with registry. In your version 1, the StorehouseImplmust have extended the UnicastRemoteObject, and in fact, there's no need for EchoImplto extend UnicastRemoteObjectfor your version 1 as there is no instance of EchoImplis registered as a remote object to the registry.

其次,类扩展的区别在于UnicastRemoteObject,如果将该类型的对象用作存根,那么您将不再需要调用UnicastRemoteObject.exportObject获取存根来与注册表绑定。在您的版本 1 中,StorehouseImpl必须扩展了UnicastRemoteObject,事实上,没有必要为您的版本 1EchoImpl扩展UnicastRemoteObject,因为没有将 的实例EchoImpl注册为注册表的远程对象。

Thirdly, you mention what'd happen if rebindis executed without bindis executed beforehand. As explained in the javadoc here, if no key name has been inserted, it will behave in the same way as if first time bindis executed.

第三,你提到如果rebind在没有bind事先执行的情况下执行会发生什么。正如javadoc的解释在这里,如果没有关键的名字已被插入时,它会以同样的方式,就好像第一次的行为bind被执行。