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通信和对象序列化技术来实现的。

最新文章

  1. DEV winform treelist设置背景图像
  2. 弹出框四 之toastr.js (完成提示框)
  3. asp.net项目在IE11下出现“__doPostBack”未定义的解决办法
  4. JAVA与数据库开发(JDBC-ODBC、SQL Server、MySQL)
  5. shell if语句
  6. UVA1588(Kickdown)。
  7. Android笔记之 文件保存、压缩与清空删除
  8. iOS_SN_CocoaPods使用详细说明( 转)
  9. mac 下 安装 mongodb 数据库
  10. (转载)python日期函数
  11. 实例讲解js正则表达式的使用
  12. LeetCode 55. Jump Game (跳跃游戏)
  13. Android探究之Gson@SerializedName
  14. Luogu P4643 【模板】动态dp
  15. angular.js 渲染
  16. CoUninitialize引发的一个错误
  17. git中的忽略配置文件中没有忽略该文件,却提交不到服务器上。
  18. python爬虫之线程池和进程池
  19. angularjs1.x的directive中的link参数element见解
  20. 【咸鱼教程】TextureMerger1.6.6 二:Sprite Sheet的制作和使用

热门文章

  1. python中如何去除列表中重复元素?
  2. Navicat12.1.7破解教程
  3. NSIS使用WinVer.nsh头文件判断操作系统版本
  4. STL中的unique()和lower_bound ,upper_bound
  5. python实现简单的百度翻译
  6. Jmeter分布式测试笔记
  7. Python - 基本数据类型及其常用的方法之列表
  8. C#——找出实现某个接口的所有类 - Hello World - CSDN博客
  9. yum与rpm常用选项
  10. 2019-7-2-Roslyn-开发-NuGet-包的-Task-编译可能遇到的问题