《java 核心课件2-第9章.ppt》由会员分享,可在线阅读,更多相关《java 核心课件2-第9章.ppt(11页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、第9章 RMIv熟悉RMI的基本原理和结构v能够熟练创建简单的RMI程序9.2 RMI的本质vRMI(Remote Method Invocation)远程方法调用;v它是Java特有的分布式计算技术,允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象的方法;v用RMI实现的远程方法调用,看起来像调用本地方法一样。客户端服务器 2.调用sayHello()方法远程对象HelloServiceImpl1.发送调用请求3.发送返回值9.3 RMI的体系结构v如下图,RMI框架采用代理,来负责客户与远程对象之间通过Socket进行通信的细节;vRMI框架为远程对象分别生成了客
2、户端代理和服务器端代理;v位于客户端的代理称类为存根(Stub);v位于服务器端的代理类称为骨架(Skeleton)。客户端服务器远程对象HelloServiceImpl3.调用sayHello()方法1.调用本地存根的sayHello()方法2.发送被编组的参数 4.发送被编组的返回值或异常由RMI框架生成的代理类远程对象的存根远程对象的骨架5.返回值或异常v当客户端调用远程对象的一个方法时,实际上是调用本地存根对象的相应方法。存根对象与远程对象具有同样的接口。存根采用一种与平台无关的编码方式,把方法的参数编码为字节序列,这个编码过程称为参数编组。RMI主要采用Java序列化机制进行参数编组
3、。接着,存根把以下请求消息发送给服务器:被访问对象的名字、被调用的方法的描述、编组后的参数的字节序列;v服务器端接收到客户端的请求信息,然后由相应的骨架对象来处理这一请求信息,骨架对象执行以下操作:反编组参数,即把参数俄字节序列反编码为参数;定位要访问的远程对象;调用远程对象的相应方法;获取方法调用产生的返回值或异常,然后对它们进行编组;把编组后的返回值或异常发送给客户端;v客户端的存根接收到服务器发送过来的编组后的返回值或异常,再对它进行反编组,就得到调用远程方法的返回结果;v存根与骨架类通过Socket进行通信;v在JDK5.0中,RMI框架会在运行时自动为远程对象生成动态代理类(包括存根
4、和骨架类),从而更彻底地封装了RMI框架的实现细节,简化了RMI框架的使用方式9.4 RMI的命名服务vRMI采用一种命名服务机制来使客户程序可以找到服务器上的一个远程对象;v在JDK的安装目录的bin子目录下有一个rmiregistry.exe程序,它是提供命名服务的注册表程序;v服务器负责创建远程对象,然后把它注册到rmiregistry注册表,客户端从注册表中获得远程对象的存根对象;vRMI的命名服务API已经被整合到Java命名与目录信息(JNDI)服务中了,以URL的形式给出;vRMI的URL以rmi:/开头,后面接服务器以及端口号,然后是一个斜线,接着是远程对象的名字:vrmi:/
5、localhost/server1默认端口为1099。ClientServerrmiregistry9.5 一个简单的应用v大致来说,创建一个RMI应用包括以下步骤:创建远程接口:继承java.rmi.Remote接口;创建远程类:实现远程接口,其构造方法必须声明抛出RemoteExcetion异常;创建服务器程序:负责在rmiregistry注册表中注册远程对象;创建客户程序:负责定位远程对象,并且调用远程对象的方法。9.5.1 创建远程接口vRMI规范要求远程对象所属的泪实现一个远程接口,并且远程接口符合以下条件:直接或间接继承java.rmi.Remote接口;接口中的所有方法声明抛出j
6、ava.rmi.RemteException;方法和参数的返回值必须是可序列化的对象。v例:public interface HelloService extends Remote String sayHello(String msg)throws RemoteException;9.5.2 提供服务器端实现类(远程类)v这个类通常继承自RemoteServer类,但它是一个抽象类,仅仅定义了服务器对象与其远程存根之间通信的基本机制;vUnicastRemoteObject类继承了抽象类RemoteServer,是一个实体类,对一个远程类而言,最简单的就是继承它,它也是当前版本RMI包中提供的
7、唯一可用的服务器端实现类。v另外,远程类的构造方法必须声明抛出RemoteExcetion异常v例:public class HelloServiceImpl extends UnicastRemoteObject implementsHelloService private String name;public HelloServiceImpl(String name)throws RemoteException this.name=name;public String sayHello(String msg)throws RemoteException return msg+from +n
8、ame;9.5.3 创建服务器类v这个类主要负责:创建远程对象;用Naming类中的rebind或bind方法对远程对象进行绑定。v例:public class SimpleServer public static void main(String args)try HelloService service1=new HelloServiceImpl(service1);HelloService service2=new HelloServiceImpl(service2);Naming.rebind(rmi:/localhost/HelloService1,service1);Naming.
9、rebind(rmi:/localhost/HelloService2,service2);System.out.println(服务器注册了两个HelloService对象);catch(RemoteException e)e.printStackTrace();catch(MalformedURLException e)e.printStackTrace();9.5.4 创建客户端类v用Naming类中的lookup方法进行远程服务查找v例:public class SimpleClient public static void main(String args)String url=rm
10、i:/192.168.1.36/;try/获得远程对象的存根对象HelloService service1=(HelloService)Naming.lookup(url+HelloService1);HelloService service2=(HelloService)Naming.lookup(url+HelloService2);System.out.println(service1.sayHello(hello);System.out.println(service2.sayHello(hello);catch(NamingException e)e.printStackTrace(
11、);catch(RemoteException e)e.printStackTrace();catch(Exception e)e.printStackTrace();现在我们建立了所有运行这个简单RMI系统所需的文件,在命令控制台下运行这个系统,必须开启三个控制台窗口,一个运行服务器,一个运行客户端,还有一个运行RMIRegistry。(1)首先运行注册程序RMIRegistry,必须在包含刚写的类的那么目录下运行这个注册程序。rmiregistry(2)运行服务器SimpleServer这个服务器就开始工作了,把接口的实现加载到内存等待客户端的联接。(3)启动客户端SimpleClient服务器端打印:服务器注册了两个HelloService对象客户端打印:hello from service1 hello from service2如果看到了上面的输出,证明已经成功的创建了一个RMI系统,并且使他正确工作了。即使运行在同一个计算机上,RMI还是使用了你的网络堆栈和TCP/IP去进行通讯,并且是运行在三个不同的Java虚拟机上。这已经是一个完整的RMI系统。9.5.5 运行RMI系统
限制150内