Java RMI 入门案例

Java Remote Method Invocation(Java RMI) 是一个 Java API, 执行远程方法的调用,相当于 Remote Procedure Calls(RPC)。Java RMI 支持直接传输序列化的 Java 类,以及分布式的垃圾回收。

案例概况

实现一个简单的 Java RMI 可通过以下四步骤:

1. 启动 rmiregistry

2. 定义服务接口,实现服务接口,通过 rmic 工具创建存根文件( stub )

3. 实现服务端功能,并启动

4. 实现客户端功能,并调用服务端服务

具体实现

1. 启动 rmiregistry

grs:~ grs$ rmiregistry 

2. 定义服务接口,实现服务接口,通过 rmic 工具创建存根文件( stub )

 定义服务接口:

package service;

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

public interface GreetService extends Remote {

    String sayHello(String name) throws RemoteException;
    
}

实现服务接口:

package service;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class GreetServiceImpl extends UnicastRemoteObject implements GreetService {

    static final long serialVersionUID = 1L;

    public GreetServiceImpl() throws RemoteException {
        super();
    }

    @Override
    public String sayHello(String name) throws RemoteException {
        return "Hello - " + name;
    }
}

根据编译后的 GreetServiceImpl,使用 rmic 生成存根文件

grs:bin grs$ rmic service.GreetServiceImpl

执行后,目录如下

grs:bin grs$ tree
.
└── service
    ├── GreetService.class
    ├── GreetServiceImpl.class
    └── GreetServiceImpl_Stub.class

3 directories, 5 files
grs:bin grs$ 

3. 实现服务端功能,并启动

package server;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

import service.GreetServiceImpl;

public class Server {

    public static void main(String[] args){
        
        try {
            LocateRegistry.createRegistry(1098);
            Naming.bind("rmi://127.0.0.1:1098/GreetService", new GreetServiceImpl());

        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (AlreadyBoundException e) {
            e.printStackTrace();
        }
    }
}

编译后,服务端文件目录结构如下:

grs:bin grs$ tree
.
├── server
│   └── Server.class
└── service
    ├── GreetService.class
    └── GreetServiceImpl.class

2 directories, 3 files
grs:bin grs$ 

启动服务端

grs:bin grs$ java -server server.Server

4. 实现客户端功能,并调用服务端服务

package client;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import service.GreetService;

public class Client {

    public static void main(String[] args){
        
        try {
            String name = "rmi://127.0.0.1:1098/GreetService";
            GreetService greetService = (GreetService) Naming.lookup(name);
            
            System.out.println(greetService.sayHello(" Thhhhhhh "));
            
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (NotBoundException e) {
            e.printStackTrace();
        }
    }
}

编译后文件目录结构如下

grs:bin grs$ tree
.
├── client
│   └── Client.class
└── service
    ├── GreetService.class
    └── GreetServiceImpl_Stub.class

2 directories, 3 files
grs:bin grs$ 

客户端调用远程端方法

grs:bin grs$ java -client client.Client
Hello -  Thhhhhhh 
grs:bin grs$ 

参考资料:

RMI 入门教程, DRY, 博客园

Introduction to Java RMI

[chapter 18] Distributed Computing : remote deployment with RMI, Head First Java

RMI, The Java Tutorials, Oracle

Java Remote Method Invocation, wikipedia

原文地址:https://www.cnblogs.com/TonyYPZhang/p/5469508.html