JavaRMI-UnicastRemoteObject:UnicastRemoteObject.exportObject()和扩展UnicastRemoteObject之间的区别是什么?
我正在准备考试,我有一个问题,我希望这里有人能回答我 它是关于RMI和远程对象的。我想知道为什么这两种实现之间有这么大的差异。一个是扩展UnicastMemoteObject,另一个是将该对象作为UnicastMemoteObject导出 我真的不明白有什么不同 接口:JavaRMI-UnicastRemoteObject:UnicastRemoteObject.exportObject()和扩展UnicastRemoteObject之间的区别是什么?,java,interface,export,rmi,Java,Interface,Export,Rmi,我正在准备考试,我有一个问题,我希望这里有人能回答我 它是关于RMI和远程对象的。我想知道为什么这两种实现之间有这么大的差异。一个是扩展UnicastMemoteObject,另一个是将该对象作为UnicastMemoteObject导出 我真的不明白有什么不同 接口: public interface EchoI extends Remote { public String echo() throws RemoteException } 这是服务器代码(版本1): 这将是第2版: pu
public interface EchoI extends Remote {
public String echo() throws RemoteException
}
这是服务器代码(版本1):
这将是第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);
...
}
}
我的问题是:这两者有什么区别
在第一个版本中,注册表是显式创建的,而且远程对象是在重新绑定中创建的
我真的很好奇,为什么首先我需要自己创建注册表,而不需要显式导出对象,只需要使用命名
重新绑定它。该对象以前是否已绑定到注册表,或者我是否可以改用绑定?如果对象以前没有绑定,并且重新绑定被排除,会发生什么
在第二个版本中,注册表似乎已经创建。
为什么绑定到命名与直接绑定到注册表相同
这就是我所想的:
- 第一个类direclty实现接口UnicastRemoteObject,这意味着在运行时创建注册表,并将对象自动导出到RMI注册表
- 由于对象已绑定到注册表,因此必须进行重新绑定而不是正常绑定
- 后者明确地做到了这一切
exportObject
方法,将获得要导出的远程对象的存根
在这里,您应该按照进行操作。这里有两个问题
UnicastRemoteObject
或调用UnicastRemoteObject.exportObject()。
具体操作由您自己决定。第一种是简单和自动的;第二种方法意味着您可以扩展另一个类扩展UnicastRemoteObject
您还可以从hashCode()
和equals()
方法中获得“远程语义”的好处,这样所有存根看起来都与导出它们的远程对象相同,但这在客户端没有实际用途,实际上,它只是为了支持RMI实现本身在需要扩展任何其他类的情况下,可以调用
UnicastRemoteObject.exportObject()
,而不是扩展UnicastRemoteObject
。我认为总体效果是一样的
首先,使用
命名
类和注册表
类绑定和重新绑定远程对象与类是否扩展UnicastRemoteObject
的场景无关。请参阅以了解差异
其次,扩展UnicastRemoteObject
的类之间的区别在于,如果该类型的对象用作存根,那么您就不需要调用UnicastRemoteObject.exportObject
来获取存根以便与注册表绑定。在您的版本1中,库impl
必须扩展了UnicastRemoteObject
,事实上,EchoImpl
无需为您的版本1扩展UnicastRemoteObject
,因为没有将EchoImpl
的实例注册为注册表的远程对象
第三,您提到如果执行
rebind
,而不事先执行bind
,会发生什么。正如javadoc中所解释的,如果没有插入密钥名,它的行为将与第一次执行bind
时的行为相同。顺便说一句,您的服务器代码版本1让我感到困惑,locateRegistry无法工作,因为它没有声明感谢您的回复,但它并没有真正为我澄清问题。。。。您更喜欢现在的代码吗?;-)现在编译器更喜欢您的代码,结果是相同的,对象在RMI注册表中以提供的名称注册,并且可由客户端访问。唯一的区别是重新绑定比绑定(如果已经绑定)更具容错性。为了再次吸引更多的男士,我会把你的问题投上一票——所以第一个版本比较安全,对吗?在几乎所有的教程中,RMI对象都是以后一种方式导出的,但在我看来,我更喜欢第一个版本,而不是另一个版本……正如前面提到的,它们是等效的。区别在于重新绑定不会抛出AlreadBoundExection,我也更喜欢您的第一个选项。在你的考试中,你可以描述一种方法,并提到还有另一种选择。质量差的链接至少有两个主要错误-1.
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);
...
}
}