RMI示例

Java RMI,即远程方法调用(Remote Method Invocation),一种用于实现远程过程调用(RPC Remote procedure call)的Java API, 能直接传输序列化后的Java对象。它的实现依赖于Java虚拟机,因此它仅支持从一个JVM到另一个JVM的调用。


image.png

1.客户端从远程服务器的注册表中查询并获取远程对象引用。
2.桩对象与远程对象具有相同的接口和方法列表,当客户端调用远程对象时,实际上是由相应的桩
对象代理完成的。
3.远程引用层在将桩的本地引用转换为服务器上对象的远程引用后,再将调用传递给传输层
(Transport),由传输层通过TCP协议发送调用;
4.在服务器端,传输层监听入站连接,它一旦接收到客户端远程调用后,就将这个引用转发给其上
层的远程引用层; 5)服务器端的远程引用层将客户端发送的远程应用转换为本地虚拟机的引用
后,再将请求传递给骨架(Skeleton); 6)骨架读取参数,又将请求传递给服务器,最后由服务
器进行实际的方法调用。
5.如果远程方法调用后有返回值,则服务器将这些结果又沿着“骨架->远程引用层->传输层”向下传
递;
6.客户端的传输层接收到返回值后,又沿着“传输层->远程引用层->桩”向上传递,然后由桩来反序
列化这些返回值,并将最终的结果传递给客户端程序。

**需求分析: **

  1. 服务端提供根据ID查询用户的方法
  2. 客户端调用服务端方法, 并返回用户对象
  3. 要求使用RMI进行远程通信

代码实现
1.定义接口和pojo

package com.demo.rmi;

import java.io.Serializable;

/**
 * @author chenyi
 * @Description
 * @date 2021/12/29 9:25
 */
public class User implements Serializable {

    private Integer id;
    private String name;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

}

package com.demo.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface IUserService extends Remote {
    
    User getById(int id) throws RemoteException;

}

2.服务端和实现类

package com.demo.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;
import java.util.Map;

public class UserServiceImpl extends UnicastRemoteObject implements IUserService {
    Map userMap = new HashMap();

    protected UserServiceImpl() throws RemoteException {
        super();
        User user1 = new User();
        user1.setId(1);
        user1.setName("张三");
        User user2 = new User();
        user2.setId(2);
        user2.setName("李四");
        userMap.put(user1.getId(), user1);
        userMap.put(user2.getId(), user2);
    }
    
    @Override
    public User getById(int id) throws RemoteException { return userMap.get(id); }

}
package com.demo.rmi;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class RMIServer {
    public static void main(String[] args) {
        try {
            //1.注册Registry实例. 绑定端口
            Registry registry = LocateRegistry.createRegistry(9998);
            //2.创建远程对象
            IUserService userService = new UserServiceImpl();
            //3.将远程对象注册到RMI服务器上即(服务端注册表上)
            registry.rebind("userService", userService);
            System.out.println("---RMI服务端启动成功----");
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

}

3.客户端

package com.demo.rmi;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/*** 客户端 */
public class RMIClient {
    public static void main(String[] args) throws RemoteException, NotBoundException {
        //1.获取Registry实例
        Registry registry = LocateRegistry.getRegistry("127.0.0.1", 9998);
        //2.通过Registry实例查找远程对象
        IUserService userService = (IUserService)registry.lookup("userService");
        User user = userService.getById(2);
        System.out.println(user.getId() + "----" + user.getName());
    }

}

你可能感兴趣的:(RMI示例)