Java RMI - UnicastRemoteObject:UnicastRemoteObject.exportObject() 和 extends UnicastRemoteObject 之间有什么区别?
我正在准备考试,我有一个问题,希望这里有人能回答我。
它是关于 RMI 和远程对象的。我想知道为什么这两种实现之间有如此大的差异。一种是扩展 UnicastRemoteObject,另一种是将对象导出为 UnicastRemoteObject。
我真的不明白有什么区别
界面:
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);
...
}
}
我的问题是:这两者之间有什么区别?
在第一个版本中,注册表是显式创建的,而且远程对象是在重新绑定中创建的?
我真的很好奇,为什么首先我需要自己创建注册表,但不需要显式导出对象,只需使用 Naming
重新绑定它。该对象之前是否已绑定到注册表,或者我可以使用绑定来代替吗?如果该对象之前没有绑定并且执行了重新绑定,会发生什么?
在第二个版本中,注册表似乎已经创建了。 为什么绑定到命名与直接绑定到注册表相同?
我的想法是:
- 第一个类直接实现 UnicastRemoteObject 接口,这意味着在运行时创建注册表并将对象自动导出到 RMI 注册表。
- 由于对象已经绑定到注册表,因此必须进行重新绑定而不是正常绑定。
- 后者明确地执行了所有这些操作。
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.
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):
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:
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?
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这里有两个问题。
您可以扩展
UnicastRemoteObject
或调用UnicastRemoteObject.exportObject()。
具体操作由您决定。第一个是简单且自动的;第二种意味着您可以扩展另一个类。您可以使用外部 RMI 注册表,也可以在服务器 JVM 中自行创建。同样,你做什么取决于你自己,两种方式都有好处。
这两个问题没有交互作用。
如果您
扩展 UnicastRemoteObject
,您还可以获得hashCode()
和equals()
方法的“远程语义”优势,例如所有存根看起来都与导出它们的远程对象相同,但这在客户端没有实际用途,实际上只是为了支持 RMI 实现本身。There are two questions here.
You can either extend
UnicastRemoteObject
or callUnicastRemoteObject.exportObject().
Which you do is up to you. The first is simple and automatic; the second means you can extend another class.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.
If you
extend UnicastRemoteObject
you also get the benefit of 'remote semantics' for thehashCode()
andequals()
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.java.rmi.server.UnicastRemoteObject
用于使用 Java 远程方法协议 (JRMP) 导出远程对象并获取与远程对象通信的存根。对于下面的构造函数和静态
exportObject
方法,将获取正在导出的远程对象的存根...您应该遵循 Javadoc
java.rmi.server.UnicastRemoteObject
is used for exporting a remote object with Java Remote Method Protocol (JRMP) and obtaining a stub that communicates to the remote object.For the constructors and static
exportObject
methods below, the stub for a remote object being exported is obtained ...There you should follow the Javadoc
在需要扩展任何其他类的情况下,您可以调用
UnicastRemoteObject.exportObject()
而不必扩展UnicastRemoteObject
。整体效果我觉得是一样的。查看此
You can call the
UnicastRemoteObject.exportObject()
instead of extending theUnicastRemoteObject
in a scenario where you need to extend any other class. Overall effect is the same I think.See this
首先,绑定&使用
Naming
类和Registry
类重新绑定远程对象与类是否扩展UnicastRemoteObject
的场景无关。请参阅此处了解差异。其次,扩展 UnicastRemoteObject 的类之间的区别在于,如果该类型的对象用作存根,则无需调用 UnicastRemoteObject.exportObject 来获取存根不再用于与注册表绑定。在您的版本 1 中,
StorehouseImpl
必须扩展了UnicastRemoteObject
,事实上,EchoImpl
不需要扩展UnicastRemoteObject< /code> 对于您的版本 1,因为没有
EchoImpl
实例被注册为注册表的远程对象。第三,您提到如果在没有事先执行
bind
的情况下执行rebind
会发生什么。如 javadoc 此处,如果未插入键名,则其行为方式与第一次执行bind
时相同。Firstly, binding & rebinding remote object using
Naming
class andRegistry
class is not relevant to scenarios of whether or not a class is extendingUnicastRemoteObject
. See here for the differences.Secondly, the difference between the class extending
UnicastRemoteObject
is that if the object of that type is used as a stub, then you'll not need to callUnicastRemoteObject.exportObject
to obtain the stub anymore for binding with registry. In your version 1, theStorehouseImpl
must have extended theUnicastRemoteObject
, and in fact, there's no need forEchoImpl
to extendUnicastRemoteObject
for your version 1 as there is no instance ofEchoImpl
is registered as a remote object to the registry.Thirdly, you mention what'd happen if
rebind
is executed withoutbind
is 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 timebind
is executed.