RMI技术讲解
1、 什么是RMI?
我们知道远程过程调用(Remote Procedure Call, RPC)可以用于一个进程调用另一个进程(很可能在另一个远程主机上)中的过程,从而提供了过程的分布能力。Java 的 RMI 则在 RPC 的基础上向前又迈进了一步,即提供分布式 对象间的通讯。
RMI(Remote Method Invocation)为远程方法调用,是允许运行在一个Java虚拟机的对象调用运行在另一个Java虚拟机上的对象的方法。
这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中。
2、 RMI的用途?
RMI的 用途是为分布式Java应用程序之间的远程通信提供服务,提供分布式服务。
目前主要应用时封装在各个J2EE项目框架中,例如Spring,EJB(Spring和EJB均封装了RMI
技术)
在Spring中实现RMI(具体代码见最后一页)
在服务器端定义服务的接口,定义特定的类实现这些接口;
在服务器端使用i.RmiServiceExporter类来注册服务;
在客户端使用i.RmiProxyFactoryBean来实现远程服务的代理功能;
在客户端定义访问与服务器端服务接口相同的类
3、 RMI的局限?
RMI目前使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP是专为Java的远程对象制定的协议,由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信(意思是只支持客户端和服务器端都是Java程序的代码的远程调用)。
4、 RMI的使用局限?
    由于客户机和服务器都是使用Java编写的,二者平台兼容性的要求仅仅是双方都运行在版本兼容的Java虚拟机上。
5、 RMI应用程序的基本模型
客户端程序
服务器端程序
   
6、 RMI调用远程方法的参数和返回值
当调用远程对象上的方法时,客户机除了可以将原始类型的数据作为参数一外,还可以将对象作为参数来传递,与之相对应的是返回值,可以返回原始类型或对象,这些都是通过Java的对象序列化(serialization)技术来实现的。(换而言之:参数或者返回值如果是对象的话必须实现Serializable接口
7、 RMI体系结构
   
Stub  [stʌb]
Skeleton['skelitn]
         
远程引用层
远程引用层
虚拟连接
           
传送层
传送层
   
传送层
桩/框架(Stub/Skeleton)层:客户端的桩和服务器端的框架;
远程引用(remote reference)层:处理远程引用行为
传送层(transport):连接的建立和管理,以及远程对象的跟踪
8、 RMI类和接口(完成一个简单RMI需要用到的类)。
接口
i.server.RemoteObject(抽象类)
i.server.RemoteServer(抽象类)
i.activation.Activatable(抽象类)
i.server.UnicastRemoteObject
 
java.lang.object
istry.
LocateRegistry
(final 类)
Java.lang.SecurityManager
计算机中spring是什么意思i.Naming
(final类)
 
     
i.RMISecurityManager
java.io.IOException
i.RemoteException
一、Remote接口:是一个不定义方法的标记接口
Public interface Remote{}
在RMI中,远程接口声明了可以从远程Java虚拟机中调用的方法集。远程接口不需满足下列要求:
1、 远程接口必须直接或间接扩展i.Remote接口,且必须声明为public,除非客户端于远程接口在同一包中
2、 在远程接口中的方法在声明时,除了要抛出与应用程序有关的一场之外,还必须包括RemoteException(或它的超类,IOExcepion或Exception)异常
3、 在远程方法声明中,作为参数或返回值声明的远程对象必须声明为远程接口,而非该接口的实现类。
二、RemoteObject抽象类实现了Remote接口和序列化Serializable接口,它和它的子类提供RMI服务器函数
说一点:提供了创建远程对象并将其导出(也就是使他们能够被远程客户机所调用),所需
的方法有类UnicastRemoteObject和Activatable提供。子类可以识别远程对象引用的语义,例如服务器是简单的远程对象还是科技获得远程对象
三、LocateRegistry  final用于获得特定主机的引导远程对象注册服务器程序的引用(即创建stub),或者创建能在特定端口接收调用的远程对象注册服务程序
服务器端:向其他客户机提供远程对象服务
SomeService servcie=……;//远程对象服务
Registry Registry();//Registry是个接口,他继承了Remote,此方法返回本地主机在默认注册表端口 1099 上对远程对象 Registry 的引用。
(还有getRegistry(int port) 返回本地主机在指定 port 上对远程对象 Registry 的引用; getRegistry(String host)  返回指定 host 在默认注册表端口 1099 上对远程对象 Registry 的引用; getRegistry(String host, int port) 返回指定的 hostport 上对远程对象 Registry 的引用)
registry.bind(“I serve”,service);// bind(String name,Remote obj) 绑定对此注册表中指定 name 的远程引用。name 与该远程引用相关的名称 obj 对远程对象(通常是一个 stub)的引用
还有一些unbindString name)移除注册表中指定name的绑定。
rebindString name,Remote obj)重新绑定,如果name已存在,但是Remote不一样则替换,如果Remote一样则丢弃现有的绑定
lookup(String name) 返回注册表中绑定到指定 name 的远程引用,返回Remote
String[] list()  返回在此注册表中绑定的名称的数组。该数组将包含一个此注册表中调用此方法时绑定的名称快照。
客户机端:向服务器提供相应的服务请求。
Registry Registry();
SomeService servcie=(SomeService)registry.lookup(“I serve”);
questService();
四、Naming
Registry类类似。
其中客户端:Naming.lookup(String url)
url 格式如下"rmi://localhost/"+远程对象引用
服务器端:Registry ateRegistry(int port);
    bind(“service”,service);
五、RMISecurityManager
    RMI引用程序中,如果没有设置安全管理器,则只能从本地类路径加载stub和类,这可以确保应用程序不受由远程方法调用所下载的代码侵害。
在从远程主机下载代码之前必须执行以下代码来安装RMISecurityManager:
System.setSecurityManagernew RMISecurityManager());
具体步骤:
1、 服务器和客户端必须定义一个能够访问的接口,该接口声明能够远程调用的方法,创建接口继承Remote接口(接口中声明需要调用的远程方法(需要抛出异常))
2、 做一个实现类 实现上面创建的接口
3、 写服务器端Java程序,注册远程对象。
4、 些客户端,获得远程对象的注册表
5、 生成stubskeleton
代码:
1
package src;
i.*;
public interface RMIInterface extends Remote{
    public java.util.Date getDate()throws RemoteException;
}
2
package src;
i.*;
i.server.*;
import java.util.Date;
public class RMIImplementation extends UnicastRemoteObject implements RMIInterface {
    public RMIImplementation()throws RemoteException{
        super();
    }
   
    public Date getDate() throws RemoteException {
        // TODO Auto-generated method stub
        return new java.util.Date();
    }
}
3
package src;
i.server.*;
i.*;
public class RMIClient {
    public static void main(String[] args){
        SecurityManager()==null)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。