--- layout: post title: RMI tags: rmi Java categories: java --- Java RMI 指的是远程方法调用 (Remote Method Invocation)。RMI能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法, 其威力体现在它强大的开发分布式网络应用的能力上,它可以被看作是RPC的Java版本。 与WebService相比,RMI编写代码更加简单,在小型应用开发上更加合适,相对地,RMI只能在java中使用,而WebSerce可以跨平台。 RMI示意图: ![rmi][rmi] # Demo 定义接口,必须继承Remote ~~~java import java.rmi.Remote; import java.rmi.RemoteException; public interface HelloService extends Remote{ String sayHello() throws RemoteException; } ~~~ 实现接口,必须继承UnicastRemoteObject并在空构造中抛出RemoteException, 方法的返回值必须为原语类型或者序列化类型. ~~~java import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; public class HelloServiceImpl extends UnicastRemoteObject implements HelloService { protected HelloServiceImpl() throws RemoteException {} @Override public String sayHello() throws RemoteException { return "server says. 'Hey'"; } } ~~~ 注册服务 ~~~java import java.net.MalformedURLException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; public class RegistryBook { public static void main(String[] args) throws RemoteException, MalformedURLException { Registry r = LocateRegistry.createRegistry(Registry.REGISTRY_PORT); r.rebind("HelloService", new HelloServiceImpl()); } } ~~~ 在另一台虚拟机上运行客户端代码,需要获得服务接口文件 ~~~java import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; public class Client { public static void main(String args[]) throws RemoteException, MalformedURLException, NotBoundException { HelloService helloService = (HelloService) Naming.lookup("rmi://localhost:1099/HelloService"); System.out.println(helloService.sayHello()); } } ~~~ 注意,如果你使用的较为古老的jdk,你可能需要通过jdk内置的`rmic`命令生成`stub`以及`skeleton`文件,并将`stub`文件提供给客户端使用。 [rmi]: {{"/rmi.jpg" | prepend: site.imgrepo }}