文档章节

JAVA RMI

ashuo
 ashuo
发布于 06/21 10:11
字数 945
阅读 14
收藏 0

什么是JAVA RMI

Java RMI (Remote Method Invocation) 远程方法调用,能够让客户端像使用本地调用一样调用服务端 Java 虚拟机中的对象方法。RMI 是面向对象语言领域对 RPC (Remote Procedure Call)的完善,用户无需依靠 IDL 的帮助来完成分布式调用,而是通过依赖接口这种更简单自然的方式。Java RMI 是 Java 领域创建分布式应用的技术基石。后续的 EJB 技术,以及现代的分布式服务框架,其中的基本理念依旧是 Java RMI 的延续。

JAVA RMI 的工作原理

  1. 服务端向 RMI 注册服务绑定自己的地址;

  2. 客户端通过 RMI 注册服务获取目标地址;

  3. 客户端调用本地的 Stub 对象上的方法,和调用本地对象上的方法一致;

  4. 本地存根对象将调用信息打包,通过网络发送到服务端;

  5. 服务端的 Skeleton 对象收到网络请求之后,将调用信息解包;

  6. 然后找到真正的服务对象发起调用,并将返回结果打包通过网络发送回客户端。

开发步骤

 1、编写远程服务接口,该接口必须继承 java.rmi.Remote 接口,方法必须抛出 java.rmi.RemoteException 异常;  
 2、编写远程接口实现类,该实现类必须继承 java.rmi.server.UnicastRemoteObject 类;  
 3、运行RMI编译器(rmic),创建客户端 stub 类和服务端 skeleton 类;  
 4、启动一个RMI注册表,以便驻留这些服务;  
 5、在RMI注册表中注册服务;  
 6、客户端查找远程对象,并调用远程方法;

 

写一个小demo测试下:

1、创建远程接口,继承java.rmi.Remote接口

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


public interface SimpleService extends Remote{

    /**
     * 远程接口方法必须抛出 java.rmi.RemoteException
     * @param message
     * @return
     * @throws RemoteException
     */
    String sayHello(String message) throws RemoteException;
}

2、实现远程接口,继承 java.rmi.server.UnicastRemoteObject类,生成可以与服务端通讯的 Stub 对象

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

public class SimpleServiceImpl extends UnicastRemoteObject implements SimpleService {

    private static final long serialVersionUID = 3451921729092664613L;

    private String message;

    public SimpleServiceImpl() throws RemoteException {

    }

    public SimpleServiceImpl(String message) throws RemoteException {
        this.message=message;
    }



    @Override
    public String sayHello(String message) throws RemoteException {
        // TODO Auto-generated method stub
        return "RPC sayHello: " + message;
    }

}

3,启动RMI注册服务,指定端口为1099,将 Stub 对象绑定到注册服务上,客户端可以通过绑定的服务名查找到该远程对象。

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

public class Server {

        public static void main(String[] args){

             try {
                 //启动RMI注册服务,指定端口为1099 (1099为默认端口)   
                 //而且用命令rmiregistry启动注册服务还必须事先用RMIC生成一个stub类为它所用   
                 LocateRegistry.createRegistry(1099);

                 //创建远程对象的一个或多个实例,下面是stub对象   
                 //可以用不同名字注册不同的实例
                 //SimpleService stub=new SimpleServiceImpl("SimpleService");
                 SimpleService stub=new SimpleServiceImpl();
                 //把stub注册到RMI注册服务器上,命名为SimpleService
                 //Naming.rebind("SimpleService", stub);  

                 //也可以把stub实例注册到另一台启动了RMI注册服务的机器上     
                 Naming.rebind("rmi://localhost:1099/SimpleService",stub);

                 System.out.println("Server is ready.");
             } catch (RemoteException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("Server  failed.");
            } catch (MalformedURLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out.println("Server  failed.");
            }
        }
}

4,客户端查找远程对象,并调用远程方法

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

public class Client {

    public static void main(String[] args){
         try {

             //SimpleService simpleService = (SimpleService) Naming.lookup("SimpleService");

             //从另一台启动了RMI注册服务的机器上查找SimpleService实例   
             SimpleService simpleService = (SimpleService)Naming.lookup("rmi://localhost:1099/SimpleService");
             System.out.println("Client send");
             //调用远程方法 
             String result = simpleService.sayHello("client");
             System.out.println("Client result:"+result);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NotBoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }
}

© 著作权归作者所有

共有 人打赏支持
ashuo
粉丝 4
博文 62
码字总数 40987
作品 0
浦东
程序员
私信 提问
RMI:Java中的分布式计算框架

RMI全称是Remote Method Invocation-远程方法调用,Java RMI在JDK1.1中实现的,其威力就体现在它强大的开发分布式网络应用的能力上,是纯Java的网络分布式应用系统的核心解决方案之一。其实...

qq_39521554
05/15
0
0
用RMI实现基于Java的分布式计算(1)

向您介绍使用RMI实现Java的分布式计算。由于Java具有跨平台、代码可移植性、安全高效等广泛而强大的功能,因而在开发网络Java分布式应用的时候,可以用它自身的机制实现分布式计算。 概述 随...

山哥
2012/02/24
0
0
JDKTM 6 Documentation

JDKTM 6 Documentation Legal Notices API, Language, and VM Specs Features Guides Release Notes Tool Docs Tutorials and Training JavaTM SE 6 Platform at a Glance This document cov......

晨曦之光
2012/03/09
0
0
Java RMI之HelloWorld篇

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该...

方绍伟
2013/09/18
0
0
JDK工具jstatd用法详解(转)

jstatd,即虚拟机的jstat守护进程,主要用于监控JVM的创建与终止,并提供一个接口允许远程监控工具依附到在本地主机上运行的JVM。 用法摘要 jstatd [ options ] 命令行选项。这些选项可以是任...

easonjim
2017/09/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JeeSite 4.x 树形结构的表设计和用法

有些同仁对于 JeeSite 4 中的树表设计不太了解,本应简单的方法就可实现,却写了很多复杂的语句和代码,所以有了这篇文章。 在 JeeSite 4 中的树表设计我还是相对满意的,这种设计比较容易理...

ThinkGem
15分钟前
10
0
0022-如何永久删除Kafka的Topic

1.问题描述 使用kafka-topics --delete命令删除topic时并没有真正的删除,而是把topic标记为:“marked for deletion”,导致重新创建相同名称的Topic时报错“already exists”。 2.问题复现...

Hadoop实操
18分钟前
0
0
技术工坊|区块链中的p2p网络(上海)

区块链是一个去中心化的系统,每个节点分布在全球各地,那么节点之间是如何自发地组成网络,又如何进行通信的?区块链中的p2p网络算法与bt下载中的p2p网络有什么区别?11月28日,第29期技术工...

HiBlock
23分钟前
1
0
MySQL性能优化之char、varchar、text的区别

在存储字符串时, 可以使用char、varchar或者text类型, 那么具体使用场景呢? 参考下面这个表结构: 1、 char长度固定, 即每条数据占用等长字节空间;适合用在身份证号码、手机号码等定。 ...

hansonwong
26分钟前
0
0
并发编程系列:4大并发工具类的功能、原理、以及应用场景

一:并发工具包 1.并发工具类 提供了比synchronized更加高级的各种同步结构:包括CountDownLatch、CyclicBarrier、Semaphore等,可以实现更加丰富的多线程操作。 2.并发容器 提供各种线程安全...

游人未归
36分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部