(二)RMI详解

1.RMI的概述:

 RMI(remote method invocation)  , 可以认为是RPC的java版本

 RMI使用的是JRMP(Java RemoteMessageing Protocol), JRMP是专门为java定制的通信协议,所以踏实纯java的分布式解决方案

2. RMI的主要概念

  • Registry 即注册中心,负责注册服务;
  • Server 是提供服务的地方,真正实现约定接口的地方;
  • Client 是你的调用方,需要使用服务的一方。
    三者之间的关系如下:

 

3.实现一个RMI程序

  1. 创建远程接口, 并且继承java.rmi.Remote接口
  2. 实现远程接口,并且继承:UnicastRemoteObject
  3. 创建服务器程序: createRegistry()方法注册远程对象
  4. 创建客户端程序  (获取注册信息,调用接口方法)


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接口(表示可以进行序列化)(序列化反序列化参考上篇文章)

4.注册及调用流程



猜你喜欢

转载自blog.csdn.net/zpoison/article/details/80534522
Rmi