使用使用JavaRMI服务?一共只需要五步!
- 创建一个
Remtote
接口,
- 继承
java.rmi.Remote
。java.rmi.Remote
是一个没有任何方法的接口,它只是定义的一个规则,我们自己实现的接口必须继承它。 - 在自定义的接口中的所有方法必须抛出
RemoteException
异常。 - 在自定义接口中的所有方法的返回值和参数必须是基本数据类型或者继承了
Serializable
接口。在Java RMI使用过程中,参数需要在client打包(序列化),传送到server,在server将参数解包(反序列化),然后运行程序得出返回值。server再将返回值打包(序列化),然后传送给client,client将返回值解包(反序列化),得到最终结果。如果参数和返回值无法正确序列化与反序列化,执行结果将会出错。
public interface MyRemote extends Remote {
String sayHello() throws RemoteException;
}
- 实现
MyRemote
接口
- 实现自定义的
Remote
接口,里面的方法是client需要调用的。 - 继承
UnicastRemoteObject
,这一步的目的是让我们实现的类能像一个remote service一样工作 - 注意:实现的类必须有个抛出
RemoteException
的构造方法。 - 注册RMI服务,这个可以通过
Naming.rebind()
来完成。
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
protected MyRemoteImpl() throws RemoteException {
}
public static void main(String[] args) {
try {
MyRemoteImpl service = new MyRemoteImpl();
Naming.rebind("designpattern.proxy.rmi.MyRemote", service);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public String sayHello() throws RemoteException {
return "Server say: Hi!";
}
}
- 生成
Stubs
和Skeletons
- java有自带的工具可以生成,我们需要在
MyRemoteImpl,class
类文件的包目录下运行:
rmic packagename.MyRemoteImpl
,就可以看见该目录下生成了对应的Stubs
和Skeletons
文件。具体来说,如果你的类文件所在目录为:src/rmi/MyRemoteImpl,class
,那么你就改在src
目录下运行rmic rmi.MyRemoteImpl
- 运行
rmiregistry
- 在包含类文件所在目录与项目同名的目录下运行
rmiregistry
。这一步的目录一定不能搞错,不然会报ClassNotFoundException
。具体来说,如果你的类文件所在目录为:src/rmi/MyRemoteImpl,class
,那么你就改在src
目录下运行rmiregistry
。
- 运行service, client
public class MyRemoteClient {
public static void main(String[] args) {
new MyRemoteClient().go();
}
public void go() {
try {
MyRemote remote = (MyRemote) Naming.lookup("rmi://127.0.0.1/designpattern.proxy.rmi.MyRemote");
String s = remote.sayHello();
System.out.println(s);
} catch (Exception e) {
e.printStackTrace();
}
}
}