rmi实现,java rmi教程

  rmi实现,java rmi教程

  如何解决写爬虫IP受阻的问题?立即使用。

  Java RMI:Java远程方法调用(Java RMI)是用Java编程语言实现远程过程调用的应用编程接口。

  它使运行在客户机上的程序能够调用远程服务器上的对象。远程方法调用特性使Java程序员能够在网络环境中分布操作。RMI旨在尽可能简化远程接口对象的使用。

  我们知道,远程过程调用(RPC)可用于一个进程调用另一个进程(可能在另一个远程主机上)中的一个进程,从而提供进程分布功能。Java的RMI在RPC的基础上又前进了一步,就是提供了分布式对象之间的通信。

  RMI(远程方法调用)是一种远程方法调用,它允许在一个Java虚拟机中运行的对象调用在另一个Java虚拟机中运行的对象。

  这两个虚拟机可以在同一台计算机上的不同进程中运行,也可以在网络上的不同计算机上运行。

  【JavaRMI】

  一、工作原理

  RMI使一个Java程序能够调用网络中另一台计算机的Java对象的方法,所以调用效果就像在本地计算机上调用一样。一般来说,机器A上有一个类。通过远程调用,机器B调用这个类中的方法。

  RMI,即远程方法调用,是Enterprise JavaBeans的支柱,也是构建分布式Java应用程序的一种便捷方式。RMI非常容易使用,但是它非常强大。

  RMI基于接口,RMI架构基于一个重要的原则:定义接口和定义接口的具体实现是分开的。让我们通过一个具体的例子来建立一个简单的远程计算服务和一个使用它的客户机程序。

  二、RMI包含部分:

  1.远程服务的接口定义

  2.远程服务接口的具体实现。

  3.存根和框架文件

  4.运行远程服务的服务器。

  5.一种RMI命名服务,允许客户端发现这个远程服务。

  6.类文件的提供者(HTTP或FTP服务器)

  7.需要此远程服务的客户端程序。

  三、RMI的用途?

  RMI的目的是为分布式Java应用程序和分布式服务之间的远程通信提供服务。

  目前,主要的应用程序封装在各种J2EE项目框架中,如Spring和EJB(Spring和EJB都封装了RMI技术)。

  在Spring中实现RMI:

  定义服务器端的服务接口,定义具体的类来实现这些接口;

  在服务器端使用org . spring framework . remoting . RMI . rmiserviceexporter类注册服务;

  使用org。springframework远程处理。RMI。RMProxyFactoryBean在客户端实现远程服务的代理功能;

  在客户端定义并访问与服务器端服务接口相同的类。

  四、RMI的局限?

  RMI目前使用Java远程消息协议jrmp (Java远程消息协议)进行通信。JRMP是专门为Java远程对象设计的协议。因为JRMP是专门为Java对象设计的,所以RMI对用非Java语言开发的应用系统的支持不够。

  不能与用非Java语言编写的对象通信(这意味着只支持在客户机和服务器上远程调用Java程序的代码)。

  五、RMI的使用局限?

  因为客户端和服务器都是用Java编写的,所以两者之间的平台兼容性要求是两个客户端都运行在兼容版本的Java虚拟机上。

  六、RMI调用远程方法的参数和返回值

  在远程对象上调用方法时,客户端不仅可以将原类型的数据作为第一个参数,还可以将对象作为参数传递,对应返回值,可以返回原类型或对象,这些都是通过Java的对象序列化技术实现的。(换句话说,如果参数或返回值是一个对象,它必须实现Serializable接口)

  七、 RMI应用程序的基本模型

  八、RMI体系结构

  存根/骨架层:客户端的存根和服务器的框架;

  远程引用层:处理远程引用行为。

  传输层:连接的建立和管理,以及远程对象的跟踪。

  九、 RMI类和接口(完成一个简单RMI需要用到的类)。

  (1)远程接口:是一个没有定义方法的标记接口。

  公共接口远程{}

  在RMI中,远程接口声明了一组可以从远程Java虚拟机调用的方法。远程接口满足以下要求:

  1.远程接口必须直接或间接扩展Java.rmi.Remote接口,并且必须声明为public,除非客户端与远程接口在同一个包中。

  2.声明远程接口中的方法时,除了抛出与应用程序相关的异常之外,还必须包含RemoteException(或其超类、IOExcepion或Exception)异常。

  3.在远程方法声明中,声明为参数或返回值的远程对象必须声明为远程接口,而不是接口的实现类。

  (RemoteObject抽象类实现远程接口和序列化可序列化接口,它和它的子类提供RMI服务器函数。

  (LocateRegistry final()类用于获取特定主机的boot远程对象注册服务器程序的引用(即创建stub),或者创建可以在特定端口接收调用的远程对象注册服务程序。

  服务器:为其他客户端提供远程对象服务。

  SomeService服务=……;//远程对象服务1,Registry Registry=locate Registry . get Registry();//Registry是接口,继承Remote。此方法返回本地主机对默认注册表端口1099上的远程对象注册表的引用。

  2.getRegistry(int port)返回本地主机对指定端口上的远程对象注册表的引用;

  3.getRegistry(String host)返回指定主机对默认注册表端口1099上的远程对象注册表的引用;

  4.getRegistry(String host,int port)返回对指定主机和端口上的远程对象注册表的引用。

  5、registry.bind("I serve ",服务);//bind(String name,Remote obj)将远程引用绑定到该注册表中指定的名称。Name:与这个远程引用obj相关联的名称:对远程对象(通常是存根)的引用

  6.unbind(字符串名称)删除注册表中指定名称的绑定。

  7.rebind(字符串名称,远程对象)重新绑定。如果名称已经存在,但遥控器不同,请替换它。如果遥控器是相同的,则丢弃现有的绑定。

  8.lookup(String name)返回绑定到注册表中指定名称的远程引用,并返回Remote。

  9.String[] list()返回在此注册表中绑定的名称数组。在此注册表中调用此方法时,数组将包含绑定名称的快照。

  客户端:向服务器端提供相应的服务请求。

  registry registry=locate registry . get registry();

  SomeService servcie=(SomeService)registry . lookup(" I serve ");

  servcie . request service();

  (D)命名类类似于注册表类。

  客户:

  Naming.lookup(字符串url)

  url格式如下“rmi://localhost/”。远程对象是指服务器端:

  registry registry=locate registry . create registry(int port);

  Naming.rebind("service ",服务);RMISecurityManager类

  在RMI引用程序中,如果没有设置安全管理器,那么存根和类只能从本地类路径加载,这样可以确保应用程序免受远程方法调用下载的代码的影响。

  在从远程主机下载代码之前,必须执行以下代码来安装RMISecurityManager:

  system . setsecuritymanager(new RMISecurityManager());

  十、demo开发

  为了写一个demo,我们分为两部分,一部分是服务器端的代码,一部分是客户端的代码。客户端的代码主要是为了使用服务器端的代码。当然这段代码很简单,只是为了说明问题,实际使用起来会更复杂。

  (一)我们的宗旨

  在服务器端建立一个java项目,包括远程端的代码,定义接口,定义接口实现,然后在客户端建立一个java项目,通过RMI使用远程服务中的方法。

  (二)我们的代码结构

  (3)远程服务代码

  1.远程服务的接口定义

  第一步是构建和编译服务接口的Java代码。该接口定义了提供远程服务的所有功能。下面是源程序:

  UserManagerInterface.java

  包cn。com。TT。RMI服务器。存根;

  导入Java。RMI。远程;

  导入Java。RMI。远程异常;

  导入cn。com。TT。RMI服务器。比恩。账户;

  公共接口用户管理界面扩展远程{

  公共字符串getUserName()引发远程异常

  公共帐户getAdminAccount()引发了远程异常

  }接口必须继承遥远的类,每一个定义地方法都要抛出远程异常异常对象。

  2.接口的具体实现

  第二步就是对于上面的接口进行实现:

  UserManagerImp.java

  包cn。com。TT。RMI服务器;

  导入Java。RMI。远程异常;

  导入cn。com。TT。RMI服务器。存根。usermanagerinterface

  导入cn。com。TT。RMI服务器。比恩。账户;

  公共类UserManagerImp实现用户管理界面{

  公共UserManagerImp()引发RemoteException {

  }

  私有静态最终长串行版本uid=-3111492742628447261 l;

  公共字符串getUserName()引发RemoteException{

  返回《TT》;

  }

  公共帐户getAdminAccount()引发了RemoteException{

  帐户帐户=新帐户();

  账户。设置用户名(“TT”);

  账户。设置密码( 123456 );

  返回帐户;

  }

  }3.定义一个豆子,实现实现可序列化序列化接口。也就是可以在客户和计算机网络服务器端进行传输的可序列化对象。

  Account.java

  包cn。com。TT。RMI服务器。豆;

  导入Java。io。可序列化;

  公共类帐户实现可序列化、可克隆的{

  private static final long serialVersionUID=-1858518369668584532 l;

  私有字符串用户名;

  私有字符串密码;

  公共字符串getUsername() {

  返回用户名;

  }

  公共void setUsername(字符串用户名){

  this .用户名=用户名;

  }

  公共字符串getPassword() {

  返回密码;

  }

  公共void setPassword(字符串密码){

  this.password=密码;

  }

  }4.定义计算机网络服务器端的主程序入口。

  Entry.java

  包cn。com。TT。RMI服务器。词条;

  导入Java。RMI。alreadyboundexception

  导入Java。RMI。远程异常;

  导入Java。RMI。注册表。定位注册表;

  导入Java。RMI。注册表。注册表;

  导入Java。RMI。服务器。unicastremoteobject

  导入cn。com。TT。RMI服务器。usermanagerimp

  导入cn。com。TT。RMI服务器。存根。usermanagerinterface

  公共类条目{

  公共静态void main(String []args)引发了AlreadyBoundException,RemoteException{

  UserManagerImp用户管理器=new UserManagerImp();

  用户管理器接口用户管理器I=(用户管理器接口)unicastremoteobject。导出对象(用户管理器,0);

  //在注册表中绑定远程对象的存根

  注册表注册表=定位注册表。创建注册表(2002年);

  registry.rebind(userManager ,用户管理器I);

  System.out.println(服务器就绪);

  }

  }(四)客户端端代码

  1、把计算机网络服务器端的账户类和接口用户管理界面导出出口成冲突包,命名为:RmiServerInterface.jar。导入到客户中。

  2、项目——右键——Export——java——jar文件——下一个——选择账户类和接口用户管理界面——命名为:RmiServerInterface.jar如下图:

  3.新建一个爪哇岛项目,导入冲突包,编写客户端代码。

  4.代码

  ClientEntry.java

  包weiblog.rmi

  导入Java。RMI。notboundexception

  导入Java。RMI。远程异常;

  导入Java。RMI。注册表。定位注册表;

  导入Java。RMI。注册表。注册表;

  导入cn。com。TT。RMI服务器。存根。usermanagerinterface

  公共类ClientEntry {

  公共静态void main(String []args){

  尝试{

  注册表注册表=定位注册表。获取注册表(“localhost”,2004);

  用户管理器接口用户管理器=(UserManagerInterface)注册表。查找(“用户经理”);

  System.out.println(用户名是userManager.getAdminAccount().getUsername()

  密码userManager.getAdminAccount().get password());

  } catch(远程异常e) {

  //TODO自动生成的捕捉块

  e。printstacktrace();

  } catch (NotBoundException e) {

  //TODO自动生成的catch块

  e . printstacktrace();

  }

  }

  }5.先运行服务器端代码,再运行客户端代码,显示运行结果。客户端可以多次运行,每次都能得到服务器端对象。如果您想再次运行客户端代码,您需要更改端口号。如果不改,会显示端口号被占用。

  更多java知识,请关注java基础课程专栏。以上是Java RMI图文讲解的详细内容(有例子)。请多关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: