RMI是什么?
RMI为分布式系统交互提供了一种解决方案。
RMI底层通过网络实现运行在不同环境中的java系统间相互调用方法,就如同调用本地方法一样。
基于RMI的开发步骤:
1.编写RMI服务接口,须继承java.rmi.Remote类,而且所有方法都需要声明抛出java.rmi.RemoteException异常,所有参数均须实现序列化。
2.编写接口实现类,须继承UnicastRemoteObject类,实现上步骤中定义的接口,由于是序列化的类因此需要定义serialVersionUID字段。
3.注册RMI服务,即将服务对象绑定到指定端口上。
4.编写客户端远程调用的代码。
一个简单示例:
在服务端,即提供远程方法的一端
1 定义RMI服务接口
package test.rmi; import java.rmi.Remote; import java.rmi.RemoteException; /** * RMI服务 * 2012-7-19 下午05:58:06 * */ public interface RmiTestService extends Remote { public String getMessage(String p) throws RemoteException; }
这些接口一般达成jar包发给客户端,供客户端编译时使用。
2 实现接口
package test.rmi; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; /** * 服务实现 * 2012-7-19 下午06:01:04 */ public class RmiTestServiceImpl extends UnicastRemoteObject implements RmiTestService { private static final long serialVersionUID = 1L; /** * @throws RemoteException */ protected RmiTestServiceImpl() throws RemoteException { super(); } /* (non-Javadoc) * @see test.rmi.RmiTestService#getMessage(java.lang.String) */ @Override public String getMessage(String p) throws RemoteException { // TODO Auto-generated method stub System.out.println("收到请求参数:" + p); return "Rmi:" + p; } }
3 编写RMI服务注册代码
package test.rmi; import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; /** * RMI服务器 * 2012-7-19 下午06:04:39 */ public class RmiServer { private int port = 9123; private String ip = "127.0.0.1"; /** * 开启RMI服务 */ public void start(){ try { LocateRegistry.createRegistry(port); // 创建一个远程对象 RmiTestService comm = new RmiTestServiceImpl(); Naming.bind("//" + ip + ":" + port + "/comm", comm); } catch (RemoteException e) { System.out.println("创建远程对象发生异常!" + e.toString()); e.printStackTrace(); } catch (AlreadyBoundException e) { System.out.println("发生重复绑定对象异常!" + e.toString()); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("发生URL畸形异常!" + e.toString()); e.printStackTrace(); } } public static void main(String []argus){ RmiServer server = new RmiServer(); System.out.println("启动RMI服务..."); server.start(); System.out.println("RMI服务已经启动"); } }
在客户端,即调用远程方法的一端
首先应添加服务端提供的接口jar包,以便于本地编译。
4 客户端远程方法调用
package test.rmi.client; import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import test.rmi.RmiTestService; /** * 客户端调用RMI服务 * 2012-7-19 下午06:14:11 */ public class RmiTestClient { private int port = 9123; private String ip = "192.168.1.19"; private RmiTestService service; /** * 获取远程服务实例 * @return */ public RmiTestService getService(){ if (this.service == null) { try { // 在RMI服务注册表中查找名称为RmiMonitorService的对象,并调用其上的方法 service = (RmiTestService) Naming.lookup("rmi://" + ip + ":" + port + "/comm"); } catch (NotBoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } return service; } /** * 本地通过调用远程对象的方法实现远程方法调用 * @param p * @return */ public String getMessage(String p){ String rt = null; try { rt = this.getService().getMessage(p); } catch (RemoteException e) { e.printStackTrace(); } return rt; } /** * TODO(简要描述方法的作用) * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub RmiTestClient client = new RmiTestClient(); System.out.println("调用远程方法..."); String rt = client.getMessage("hello"); System.out.println("rmi返回:" + rt); } }
测试运行:
首先运行RmiServer.main方法,启动RMI服务,然后运行RmiTestClient.main方法调用rmi服务。
上面是一个简单的RMI应用实例,其中没有添加安全措施,如果服务对外网开放则需要添加安全措施,这部分内容,慢慢研究,后面再补充。