方法的调用都是发生在相同堆上的两个对象之间
package com.demo3;
public class Foo {
void go(){
Bar b= new Bar();
b.doStuff();
}
public static void main(String[] args) {
Foo f = new Foo();
f.go();
}
}
如果要调用不同机器上的对象的方法呢???----解决办法:远程调用RMI
远程过程调用的设计:
要创建4种东西:服务器、客户端、服务器辅助设施和客户端辅助设施
(1)创建客户端和服务器应用程序。服务器应用程序是个远程服务,是个带有客户端会调用的方法的对象。
(2)创建客户端和服务端的辅助设施(helper)。它们会处理所有客户端和服务器的底层网络输入/输出细节,让你的客户端和程序好像在处理本机调用一样。
辅助设施的任务
辅助设施是个实际上执行通信的对象。它们会让客户端感觉好像是调用本机的对象。事实上正是这样。客户端调用辅助设施的方法,就好像客户端就是服务器一样。客户端是真正服务的代理(proxy)
在服务器这端,服务器的辅助设施会通过Socket连接来自客户端设施的要求,解析打包送来的而消息,然后调用真正的服务。因此对服务对象来说此调用来自于本地。
服务的辅助设施取得返回值之后就把它包装然后送回去(通过Socket的输出串流)给客户端的辅助设施。客户端的辅助设施会解开这些信息传给客户端的对象
调用方法的过程:
(1)客户端对象对辅助设施对象调用doBigThing()
(2)客户端辅助设施把调用信息打包通过网络送到服务器的辅助设施
(3)服务端的辅助设施解开来自客户端辅助设施的信息,并以此调用真正的服务。
关于RMI的几点总结:
1、在某堆上的对象无法进行另外堆上的对象引用。
2、Java Remote Method Invocation(RMI)让你感觉上像是调用远程对象的方法,但其实不是。
3、当客户端调用远程对象的方法时,其实是调用代理上的方法,此代理被称为stub。
4、stub是个低层网络细节的辅助性对象,它会把方法的调用包装起来送到服务器上。
5、要创建远程服务的话,你就必须要以远程接口来启动。
6、远程接口必须要extend过java.rmi.Remote这个接口。且所有的方法都必须声明RemoteException.
7、你的远程服务会实现远程接口。
8、远程服务应该要继承UnicastObject(技术上也有其他方法可以创建远程对象,但这是最简单的方式)。
9、远程服务必须要声明RemoteException的构造函数(因为父类的构造函数声明了)。
10、远程服务的对象必须要向RMI registry注册
11、使用静态的Naming.remind()来注册远程服务。
12、RMI registry必须在同一台机器上与远程服务一块执行,且必须在对象的注册之前启动。
13、客户端会以Naming.lookup()查询远程服务。
14、几乎所有与RMI有关的都会抛出RemoteException(由编译器检查)。
关注公众号:工控技术之家,可留言提问相关问题,有需要可发送源代码