大家好,我是IT修真院武汉分院第十五期学员,一枚正直纯洁善良的JAVA程序员。
今天给大家分享一下,修真院官网JAVA任务八的一个知识点:什么是RMI,为什么要使用RMI框架?
1.背景介绍
RMI是Java的一组拥护开发分布式应用程序的API。RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协议(Java Remote Method Protocol)。
Java远程方法协议(英语:Java Remote Method Protocol,JRMP)是特定于Java技术的、用于查找和引用远程对象的协议。这是运行在Java远程方法调用(RMI)之下、TCP/IP之上的线路层协议 通过RMI技术,本地虚拟机JVM可以调用存在于另外一个JVM中的对象方法,就好像该虚拟机调用存在于本地JVM的某个对象方法一样。而另外一个JVM可以与本地JVM在同一台物理机,也可以属于不同的物理机。 常见的可以实现远程调用的技术还包括了 RPC,CORBA,Web Service。
2.知识剖析
RMI基本实现说明
我们希望在两个JVM虚拟机远程方法调用可以以常规方法进行调用,而无需关心数据的发送接收以及解析之类的问题。 解决的思路是,在客户端安装一个代理(proxy),代理是位于客户端虚拟机中的一个对象,他对于客户端对象, 看起来就像访问的远程对象一样,客户端代理会使用网络协议与服务器进行通信。 同样的实现的服务端代码的程序员也不希望需要手动编码对客户端的调用进行复杂的处理, 所以在服务器端也会有一个代理对象来进行通信的繁琐工作。
名词解释
在RMI中,客户端的代理对象被称为存根(Stub),存根位于客户端机器上,它知道如何通过网络与服务器联系。存根会将远程方法所需的参数打包成一组字节。
对参数编码的过程被称为参数编组(parameter marshalling),参数编组的目的是将参数转换成适合在虚拟机之间进行传递的形式。 在RMI协议中,对象时使用序列化机制进行编码的。
RMI 优点
RMI大大增强了java开发分布式应用的能力,例如可以将计算方法复杂的程序放在其他的服务器上,主服务器只需要去调用, 而真正的运算是在其他服务器上进行,最后将运算结果返回给主服务器,这样就减轻了主服务器的负担,提高了效率(但是也有其他的开销)。
RMI 调用步骤
1,客户对象调用客户端辅助对象上的方法
2,客户端辅助对象打包调用信息(变量,方法名),通过网络发送给服务端辅助对象
3,服务端辅助对象将客户端辅助对象发送来的信息解包,找出真正被调用的方法以及该方法所在对象
4,调用真正服务对象上的真正方法,并将结果返回给服务端辅助对象
5,服务端辅助对象将结果打包,发送给客户端辅助对象
6,客户端辅助对象将返回值解包,返回给客户对象
7,客户对象获得返回值
对于客户对象来说,步骤2-6是完全透明的
Spring rmi 服务端
在Web工程中添加接口,普通接口,这里无需继承其他public interface 接口的实现类
该服务端Web工程中添加Spring的bean配置文件,比如命名为rmiServer.xml 主函数 启动
客户端 在源文件src下建立一个rmiClient.xml
客户端程序:在maven clean package 把客户端打成jar包然后在服务端引入
3.常见问题
1.如何使用Spring RMI发布服务
3.打包问题
4.解决方案
1. 服务端使用Spring 配置来注入RmiServiceExporter对象来发布服务
2. 使用 maven-shade-plugin 将其打包为jar文件.
6.扩展思考
1.如何使用插件打包jar包
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.fgh.task2.Server.Server</mainClass>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
2.rmi为什么要跑RemoteException
由于远程方法的本质还是网络通信,只不过隐藏了底层实现,网络通信是经常会出现异常的,所以接口的所有方法都要抛出RemoteException来说明此方法是有风险的;
3.JAVARMI和SPRINGRMI的区别
区别
在Spring环境使用RMI时,可以省略以下几点:
1、接口类不需要继承Remote,方法不需要抛出RemoteException异常对象。
2、实现类不需要继承UnicastRemoteObject。
3、RMI服务自动注册。