大家好,我是IT修真院武汉分院第15期的学员,一枚正直纯洁善良的JAVA程序员。今天给大家分享一下,修真院官网JAVA任务8的知识点——什么是RMI
1.背景介绍
2.知识剖析
3.常见问题
4.编码实战
5.扩展思考
6.参考文献
7.更多讨论
RMI全称是Remote Method Invocation-远程方法调用,是纯Java的网络分布式应用系统的核心解决方案之一。Java RMI 支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。
在RMI中,核心是远程对象(remote object),除了对象本身所在的虚拟机,其他虚拟机也可以调用此对象的方法,而且这些虚拟机可以不在同一个主机上。每个远程对象都要实现一个或者多个远程接口来标识自己,声明了可以被外部系统或者应用调用的方法
RMI的通信模型
从方法调用角度来看:RMI要解决的问题,是让客户端对远程方法的调用可以相当于对本地方法的调用而屏蔽其中关于远程通信的内容,即使在远程上,也和在本地上是一样的。
从客户端-服务器模型来看,客户端程序直接调用服务端,两者之间是通过JRMP( Java Remote Method Protocol)协议通信
由于JRMP是专为Java对象制定的,用Java RMI开发的应用系统可以部署在任何支持JRE的平台上。但由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。
实际上,客户端只与代表远程主机中对象的Stub对象进行通信,丝毫不知道Server的存在。 客户端只是调用Stub对象中的本地方法,Stub对象是一个本地对象,它实现了远程对象向外暴露的接口,也就是说它的方法和远程对象暴露的方法的签名是相同的。 客户端认为它是调用远程对象的方法,实际上是调用Stub对象中的方法。可以理解为Stub对象是远程对象在本地的一个代理,当客户端调用方法的时候,Stub对象会将调用通过网络传递给远程对象。
基于RMI的一次完整的远程通信过程的原理:
1、客户端发起请求,请求转交至RMI客户端的stub类;
2、stub类将请求的接口、方法、参数等信息进行序列化;
3、基于tcp/ip将序列化后的流传输至服务器端;
4、服务器端接收到流后转发至相应的skeleton类;
5、skeleton类将请求的信息反序列化后调用实际的处理类;
6、处理类处理完毕后将结果返回给skeleton类;
7、Skeleton类将结果序列化,通过tcp/ip将流传送给客户端的stub;
8、stub在接收到流后反序列化,将反序列化后的Java Object返回给调用者。
3.1 如何使用Spring RMI发布服务,在客户端链接服务
服务端使用Spring 配置来注入RmiServiceExporter对象来发布服务,在客户端,用RmiProxyFactoryBean连接它。
3.2 数据的传递问题
在Java程序中引用类型的参数传递是按引用传递的,对于在同一个虚拟机中的传递时是没有问题的,因为的参数的引用对应的是同一个内存空间,但是对于分布式系统中,由于对象不再存在于同一个内存空间,虚拟机A的对象引用对于虚拟机B没有任何意义
可以将对象序列化为字节流,实现java.io.Serializable接口
3.3 rmi为什么要抛出 RemoteException
由于远程方法的本质还是网络通信,只不过隐藏了底层实现,网络通信是经常会出现异常的,所以接口的所有方法都要抛出RemoteException来说明此方法是有风险的
远程对象的发现问题
调用远程对象的方法之前需要一个远程对象的引用,如何获得这个远程对象的引用在RMI中是一个关键的问题,可以将远程对象的发现类比于IP地址的发现;
日常使用网络时,基本上都是通过域名来定位一个网站,但是实际上网络是通过IP地址来定位网站的,因此其中就需要一个映射的过程,域名系统(DNS)就是为了这个目的出现的,在域名系统中通过域名来查找对应的IP地址来访问对应的服务器。那么对应的,IP地址在这里就相当于远程对象的引用,而DNS则相当于一个注册表(Registry)。而域名在RMI中就相当于远程对象的标识符,客户端通过提供远程对象的标识符访问注册表,来得到远程对象的引用。这个标识符是类似URL地址格式的,它要满足的规范如下:
该名称是URL形式的,类似于http的URL,schema是rmi;
格式类似于rmi://host:port/name,host指明注册表运行的注解,port表明接收调用的端口,name是一个标识该对象的简单名称。
http://www.shouce.ren/api/spring2.5/ch17s02.html
https://blog.csdn.net/lmy86263/article/details/72594760