[英]Java RMI - UnicastRemoteObject: what is the difference between UnicastRemoteObject.exportObject() and 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
重新绑定它。 该对象之前是否已绑定到注册表,或者我可以使用bind吗? 如果对象之前没有绑定并重新绑定,会发生什么?
在第二个版本中,注册表似乎已经创建。 为什么绑定命名与直接绑定到注册表相同?
这就是我的想法:
这里有两个问题。
您可以扩展UnicastRemoteObject
或调用UnicastRemoteObject.exportObject().
你做的由你决定。 第一个是简单和自动的; 第二个意味着你可以扩展另一个类。
您可以使用外部RMI注册表,也可以在服务器JVM中自行创建。 你做的再取决于你,两种方式都有优势。
这两个问题没有互动。
如果extend UnicastRemoteObject
您还可以获得hashCode()
和equals()
方法的“远程语义”的好处,这样所有存根看起来都与导出它们的远程对象相同,但这对于它没有实际用途。客户端,实际上只是支持RMI实现本身。
java.rmi.server.UnicastRemoteObject
用于使用Java远程方法协议(JRMP)导出远程对象并获取与远程对象通信的存根。
对于下面的构造函数和静态exportObject
方法,获取正在导出的远程对象的存根...
在那里你应该遵循Javadoc
您可以调用UnicastRemoteObject.exportObject()
而不是在需要扩展任何其他类的场景中扩展UnicastRemoteObject
。 我认为整体效果是一样的。
首先,使用Naming
类和Registry
类绑定和重新绑定远程对象与类是否正在扩展UnicastRemoteObject
方案无关。 请看这里的差异。
其次,扩展UnicastRemoteObject
的类之间的区别在于,如果该类型的对象用作存根,那么您不需要再调用UnicastRemoteObject.exportObject
来获取存根以便与注册表绑定。 在您的版本1中, StorehouseImpl
必须扩展UnicastRemoteObject
,事实上, EchoImpl
不需要为您的版本1扩展UnicastRemoteObject
,因为没有EchoImpl
实例被注册为注册表的远程对象。
第三,你提到如果在没有bind
情况下执行rebind
bind
被事先执行会发生什么。 正如这里的javadoc所解释的,如果没有插入键名,它的行为方式与第一次执行bind
行为方式相同。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.