1.RMI的概述:
RMI(remote method invocation) , 可以认为是RPC的java版本
RMI使用的是JRMP(Java RemoteMessageing Protocol), JRMP是专门为java定制的通信协议,所以踏实纯java的分布式解决方案
2. RMI的主要概念
- Registry 即注册中心,负责注册服务;
- Server 是提供服务的地方,真正实现约定接口的地方;
- Client 是你的调用方,需要使用服务的一方。
3.实现一个RMI程序
- 创建远程接口, 并且继承java.rmi.Remote接口
- 实现远程接口,并且继承:UnicastRemoteObject
- 创建服务器程序: createRegistry()方法注册远程对象
- 创建客户端程序 (获取注册信息,调用接口方法)
3.1本文用获取用户信息为简单案例
1.用户实体
import java.io.Serializable; /** * @author zpoison * @data 2018/5/31/031 18:10 */ public class User implements Serializable { private String name; private int age; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", sex='" + sex + '\'' + '}'; } }
2.UserService接口提供业务处理方法:
import java.rmi.Remote; import java.rmi.RemoteException; /** * @author zpoison * @data 2018/6/1/001 9:00 */ public interface UserService extends Remote { //每一个定义的方法都必须抛出一个RemoteException异常对象 //我们可供远程调用的方法就是通过这里开公开 //同过姓名获取用户信息 public String getUserInfo(String name) throws RemoteException; }
3.UserServiceImpl接口实现这里提供了一个简单的用户验证逻辑
import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; /** * @author zpoison * @data 2018/6/1/001 9:03 */ public class UserServiceImpl extends UnicastRemoteObject implements UserService { protected UserServiceImpl() throws RemoteException { } @Override public String getUserInfo(String name) throws RemoteException { //模拟数据查询功能 User user =new User(); user.setAge(19); user.setName("小明"); user.setSex("男"); //验证用户是否存在 if (user.getName().equals(name)){ return user.toString(); } return "用户:"+name+"不存在"; } }
4.注册服务
import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; /** * @author zpoison * @data 2018/6/1/001 9:10 */ public class UserServer { public static void main(String[] args) { try { UserService userService =new UserServiceImpl(); LocateRegistry.createRegistry(8888); Naming.bind("rmi://localhost:8888/UserService", userService); System.out.println("server start success"); } catch (RemoteException e) { e.printStackTrace(); } catch (AlreadyBoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } } }
5.客户端调用服务(需要依赖服务接口)
import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; /** * @author zpoison * @data 2018/6/1/001 9:13 */ public class UserClient { public static void main(String[] args) { try { UserService userService=(UserService) Naming.lookup("rmi://localhost:8888/UserService"); System.out.println(userService); System.out.println(userService.getUserInfo("小明")); } catch (NotBoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } }
服务端启动信息:
客户端信息:
注意点:
实体User类必须实现 java.io.Serializable接口(表示可以进行序列化)(序列化反序列化参考上篇文章)