RMI是什么?

RMI是指Java Remote Method Invocation,远程方法调用,RMI是Java的一组拥护开发分布式应用程序的API。RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协议(Java
Remote Method Protocol)。

简单来说,RMI可以是我们的程序从一台服务器,调用另一台服务器上的方法,就像调用本地服务一样方便。

RMI基本原理

RMI 构建三个抽象层, 高层覆盖低层, 分别负责Socket通信, 参数和结果的序列化和反序列化等工作。存根( Stub) 和骨架( Skeleton) 合在一起形成了 RMI 构架协议。下面的引用层被用来寻找各自的通信伙伴, 在这一层还有一个提供名字服务的部分,
称为注册表( registry) 。最下一层是传输层, 是依赖于 TCP/IP 协议实现客户机与服务器的互联。

当客户端调用远程对象方法时, 存根负责把要调用的远程对象方法的方法名及其参数编组打包,并将该包向下经远程引用层、传输层转发给远程对象所在的服务器。通过 RMI 系统的 RMI 注册表实现的简单服务器名字服务, 可定位远程对象所在的服务器。该包到达服务器后,
向上经远程引用层, 被远程对象的 Skeleton 接收, 此 Skeleton 解析客户包中的方法名及编组的参数后, 在服务器端执行客户要调用的远程对象方法, 然后将该方法的返回值( 或产生的异常) 打包后通过相反路线返回给客户端, 客户端的 Stub 将返回结果解析后传递给客户程序。事实上, 不仅客户端程序可以通过存根调用服务器端的远程对象的方法, 而服务器端的程序亦可通过由客户端传递的远程接口回调客户端的远程对象方法。在分布式系统中, 所有的计算机可以是服务器, 同时又可以是客户机。

RMI实例

要注意,
任何远程调用的对象,都必须实现Java.rmi.Remote接口
任何可以被远程调用的对象都必须扩展该类:Java.rmi.Server.UnicastRemoteObject
任何可以被远程调用的方法,都必须抛出RemoteException异常

定义接口

package com.tfjy.test;
import java.rmi.Remote;
import java.rmi.RemoteException; /**
* Created by L on 2017-06-29.
*/
public interface IHello extends Remote {
public String helloWorld() throws RemoteException; public String sayHelloToSomeBody(String someBodyName) throws RemoteException; }

实现该接口

package com.tfjy.test;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject; /**
* Created by L on 2017-06-29.
*/
public class HelloImpl extends UnicastRemoteObject implements IHello { /**
* 因为UnicastRemoteObject的构造方法抛出了RometeException异常,因此这里默认的构造方法必须写,必须
* 声明抛出了RemoteException异常
* @throws RemoteException
*/
public HelloImpl() throws RemoteException{}
public String helloWorld() {
return "Hello World";
} public String sayHelloToSomeBody(String someBodyName) throws RemoteException{
return "你好"+someBodyName+"!";
}
}

创建服务端

package com.tfjy.test;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry; /**
* Created by L on 2017-06-29.
*/
public class HelloServer {
public static void main(String args[]){
try {
//创建一个远程对象
IHello rhello = new HelloImpl();
//本地主机上的远程对象注册表Registry的实例,并指定端口为8888,这一步必不可少
// (Java默认的端口据是1.99,如果缺少注册表创建,则无法绑定对象到远程注册表上)
LocateRegistry.createRegistry(8888); //把远程对象注册到RMI注册服务器上,并命名为RHello
//绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略,下面两种写法都是正确的)
Naming.bind("rmi://localhost:8888/RHello",rhello);
//Naming.bind("//localhost:8888/RHello",rhello);
System.out.println(">>>>>>>>>INFO:远程IHello对象绑定成功!");
} catch (RemoteException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}
}
}

创建客户端

package com.tfjy.test;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException; /**
* Created by L on 2017-06-29.
*/
public class HelloClient {
public static void main(String args[]){
try {
//在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法
IHello rhello= (IHello) Naming.lookup("rmi://localhost:1099/RHello");
System.out.println(rhello.helloWorld());
System.out.println(rhello.sayHelloToSomeBody("咩哈哈"));
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}

启动

我用的是idea,首先启动Server端,等待控制台打印如下语句:

然后启动Client端,它将连接服务端并打印如下语句:

总结

RMI是实现EJB的基础,通过RMI,J2EE将EJB组件创建为远程对象。RMI是远程过程调用(RPC)的一种面向对象实现(Java实现)。RMI底层是通过socket通信和对象序列化技术来实现的。

[J2EE规范]RMI简单实例 标签: j2ee实例 2017-06-29 18:05 217人阅读 评论(13)的更多相关文章

  1. [J2EE规范]JDBC简单例子 标签: 数据库j2eejdbcjava 2017-06-29 10:55 353人阅读 评论(12)

    JDBC是什么? JDBC是java数据库连接(Java Database Connectivity),它是用于java编程语言和数据库之间的数据库无关连接的标准Java API,就是说,JDBC是用 ...

  2. makefile基础实例讲解 分类: C/C++ 2015-03-16 10:11 66人阅读 评论(0) 收藏

    一.makefile简介 定义:makefile定义了软件开发过程中,项目工程编译链.接接的方法和规则. 产生:由IDE自动生成或者开发者手动书写. 作用:Unix(MAC OS.Solars)和Li ...

  3. 使用DataContractJsonSerializer类将类型实例序列化为JSON字符串和反序列化为实例对象 分类: JSON 前端 2014-11-10 10:20 97人阅读 评论(1) 收藏

    一.JSON简介 JSON(JavaScript Object Notation,JavaScript对象表示法)是一种轻量级的数据交换格式. JSON是"名值对"的集合.结构由大 ...

  4. 【批量添加】-SqlBulkCopy语句 标签: sql批量添加 2015-12-20 14:39 1367人阅读 评论(33)

    上篇博客我们介绍了通过拼接sql字符串的方法来对sql数据库进行批量添加,但是通过语句拼接insert语句有个缺点,就是每次最多只能添加1000条.当时我们另外一个界面也用到了批量添加,但是这个界面轻 ...

  5. [运维]Dell R710 raid配置 标签: raid运维 2017-04-15 19:35 581人阅读 评论(16)

    Dell R系列的一些服务器,raid的配置都大同小异,公司大部分的服务器,都是Dell R710型号的,这个型号的raid界面配置起来还是很简单的,下面来跟随小编体验一下raid如何配置吧.ps:图 ...

  6. [ITOO]动态建库 标签: 库数据库mysql 2016-07-17 21:23 241人阅读 评论(2) 收

    最近一直在做权限系统的动态建库,动态建库,说白了就是在你点击"注册"按钮的时候,根据你输入的信息,来创建一个企业所需要的数据库的过程,因为现阶段并没有提供购买等功能,所以暂时咱们是 ...

  7. 【uml】之类图中的关系 标签: uml图形类 2014-11-29 09:02 1198人阅读 评论(23)

    uml早就画完了图,但是自己迟迟没有总结,因为总觉的自己把握的不到位,虽然现在也还是不到位,废话少说,上篇博客总结了用例图中的几种关系,这篇就讨论一下类图中的几种关系. 在uml的所有图中,就我目前的 ...

  8. svn总结 标签: svn开源软件 2015-05-09 17:31 513人阅读 评论(11) 收藏

    说到SVN,就不得不说CVS,CVS 是一个C/S系统,是一个常用的代码版本控制软件.主要在开源软件管理中使用.与它相类似的代码版本控制软件有subversion.多个开发人员通过一个中心版本控制系统 ...

  9. JAVA 显示图片的简单源码 分类: Java Game 2014-08-14 10:10 77人阅读 评论(0) 收藏

    此代码的原理就是用JLabel来加载图片,再将JLabel放入JFrame中, package com.mywork; import javax.swing.ImageIcon; import jav ...

随机推荐

  1. 廖雪峰Java10加密与安全-3摘要算法-5Hmac

    1 比较MD5和HamcMD5 HmacMD5可以看作带安全salt的MD5 import javax.crypto.KeyGenerator; import javax.crypto.Mac; im ...

  2. ajax传输数据

    AJAX向后台传输数//1 直接在url中传递 $.ajax({ type: "POST", url: "/testAjax/addUser?id=1&name= ...

  3. 19-10-18-Night-U

    话说T3: 一句话题意……见过这个嘛…… 于是:$\sum \limits_{i!=j} \binom{a_i+b_i+a_j+b_j}{a_i+a_j}$ ------------前言结束----- ...

  4. PHP7中标量类型declare的用法详解

    这篇文章主要介绍了PHP7标量类型declare用法,结合实例形式分析了PHP7中标量类型declare的功能.特性与相关使用技巧,需要的朋友可以参考下 本文实例讲述了PHP7标量类型declare用 ...

  5. Cesium打包命令总结

    引言 Cesium实验室QQ群里有人在问Cesium的打包问题.我想干脆总结一下Cesium的打包命令特点,写篇文章,顺带庆祝一下1024程序员节.. Cesium的npm脚本有好多,其中几个和打包相 ...

  6. Luogu P1092 虫食算(枚举+剪枝)

    P1092 虫食算 题面 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6633 4 ...

  7. Leetcode551.Student Attendance Record I学生出勤记录1

    给定一个字符串来代表一个学生的出勤纪录,这个纪录仅包含以下三个字符: 'A' : Absent,缺勤 'L' : Late,迟到 'P' : Present,到场 如果一个学生的出勤纪录中不超过一个' ...

  8. Linux程序包管理初步-rpm的使用

    在Linux系统上,一般而言,对于程序包管理器来说分为三类: debian:dpt,dpkg;             (程序包后缀.deb) rhel:rpm (程序包后缀.rpm) suse:rp ...

  9. .net NPOI C#处理Excel的类库使用

    ----------------------------------------------------------- .net NPOI C#处理Excel的类库使用https://www.nuge ...

  10. 基于MaxCompute的媒体大数据开放平台建设

    摘要:随着自媒体的发展,传统媒体面临着巨大的压力和挑战,新华智云运用大数据和人工智能技术,致力于为媒体行业赋能.通过媒体大数据开放平台,将媒体行业全网数据汇总起来,借助平台数据处理能力和算法能力,将有 ...