Java RMI-远程方法调用

一、Java RMI概观

     RMI英文全称为:Remote Method Invocation,中文意思为:远程方法调用。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。

     RMI提供了客户辅助对象和服务辅助对象,为客户辅助对象创建和服务对象相同的方法。RMI的好处在于你不必亲自写如何网络代码和I/O代码。客户程序远程调用(即真正的服务所在)就和运行客户自己的本地机JVM上对对象进行正常方法调用一样。

    RMI将客户辅助对象成为stub(桩),服务辅助对象成为skeleton(骨架)。

    RMI结构图如下:

二、Java中如何利用RMI进行远程方法调用呢?

步骤如下:

1、制作远程接口

2、制作远程的实现

3、利用rmic产生stub和skeleton

4、启动RMI registry(rmiregistry)

5、开始远程服务

 

三、例子程序

三、例子程序

MyRemote.java

/**
 * 服务器端   远程接口
 */

package RMIDemo;

/*
 * RemoteException和远程接口在java.rmi包中
 * */
import java.rmi.*;

/*
 * 定义一个远程接口,它必须扩展自java.rmi.Remote接口。
 * */
public interface MyRemote extends Remote {
 /**
  * 所有的远程方法都必须抛出RemoteException异常。
  * @return
  * @throws RemoteException
  */
 public String sayHello() throws RemoteException;
}
MyRemoteImpl.java

/**
 * 远程服务(实现)
 */
package RMIDemo;

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
 *
 * @author ccf
 *
 */

/**
 * 要想创建一个远程对象,扩展UnicastRemoteObject是最容易的方法。
 * 其中,MyRemote接口是你必须实现的远程接口
 */
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
 /**
  * 你必须实现远程接口。当然你必须实现所有的接口方法,但请注意:可以不需要声明RemoteException。
  */
 @Override
 public String sayHello() throws RemoteException {
  // TODO Auto-generated method stub
  return "Server says: 'Hey' ";
 }
 /**
  * 你的超类(UnicastRemoteObject)构造器声明了异常,所以你必须写一个构造器,
  * 因为这意味着你的构造器正在调用不安全的代码(它的超构造器)。
  * @throws RemoteException
  */
 public MyRemoteImpl() throws RemoteException{}

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  try{
   /**
    * 先产生远程对象,再使用Naming.rebind()绑定到rmiregistry。
    * 客户将使用你所注册的名称在RMI Registry中寻找它。
    */
   MyRemote service = new MyRemoteImpl();
   Naming.rebind("RemoteHello", service);
  }catch(Exception ex){
   ex.printStackTrace();
  }
 }

}
MyRemoteClient.java

package RMIDemo;

/**
 * 用来做rmiregister lookup的Naming类在java.rmi包中。
 * 客户端测试,在客户端调用远程对象的远程方法,并返回结果。
 */
import java.rmi.*;

public class MyRemoteClient {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  
 }
 public void go(){
  try{
   /*
    * 返回值是Object类型,所以别忘记转换类型。
    * 其次,在lookup函数中你需要IP地址或主机名,还有服务器被绑定/重绑定时用的名称。
    */
   MyRemote service = (MyRemote)Naming.lookup("rmi://127.0.0.1/RemoteHello");
   
   String s = service.sayHello();
   
   System.out.println(s);
  }catch(Exception ex){
   ex.printStackTrace();
  }
 }
}

 

开发步骤:

    1、 编写并且编译接口的Java代码 
  2、 编写并且编译接口实现的Java代码 
  3、 从接口实现类中生成桩(Stub)和框架(Skeleton)类文件 
  4、 编写远程服务的主运行程序 
  5、 编写RMI的客户端程序 
  6、 安装并且运行RMI系统