先上例子,来自http://damies.iteye.com/blog/51778
HelloInterface.java、Hello.java、HelloServer.java、HelloClient.java
1.HelloInterface.java
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* 远程接口必须扩展接口java.rmi.Remote
*/
public interface HelloInterface extends Remote {
/**
* 远程接口方法必须抛出 java.rmi.RemoteException
*/
public String say() throws RemoteException;
}
2.Hello.java
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Hello extends UnicastRemoteObject implements HelloInterface {
private static final long serialVersionUID = 1L;
private String message;
public Hello(String msg) throws RemoteException {
message = msg;
}
public String say()throws RemoteException{
System.out.println("Called by HelloClient");
return message;
}
}
3.HelloServer.java
import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
public class HelloServer
{
/**
* 启动 RMI 注册服务并进行对象注册
*/
public static void main(String[] argv)
{
try
{
//启动RMI注册服务,指定端口为1099 (1099为默认端口)
//也可以通过命令 $java_home/bin/rmiregistry 1099启动
//这里用这种方式避免了再打开一个DOS窗口
//而且用命令rmiregistry启动注册服务还必须事先用RMIC生成一个stub类为它所用
LocateRegistry.createRegistry(1099);
//创建远程对象的一个或多个实例,下面是hello对象
//可以用不同名字注册不同的实例
HelloInterface hello = new Hello("Hello, world!");
//把hello注册到RMI注册服务器上,命名为Hello
Naming.rebind("Hello", hello);
//如果要把hello实例注册到另一台启动了RMI注册服务的机器上
//Naming.rebind("//192.168.1.105:1099/Hello",hello);
System.out.println("Hello Server is ready.");
}
catch (Exception e)
{
System.out.println("Hello Server failed: " + e);
}
}
}
4.HelloClient.java
import java.rmi.Naming;
public class HelloClient
{
/**
* 查找远程对象并调用远程方法
*/
public static void main(String[] argv)
{
try
{
HelloInterface hello = (HelloInterface) Naming.lookup("Hello");
//如果要从另一台启动了RMI注册服务的机器上查找hello实例
//HelloInterface hello = (HelloInterface)Naming.lookup("//192.168.1.105:1099/Hello");
//调用远程方法
System.out.println(hello.say());
}
catch (Exception e)
{
System.out.println("HelloClient exception: " + e);
}
}
}
实际情况里,HelloInterface.java是部署在两端。Hello.java、HelloServer.java部署在服务端。HelloClient.java部署在客户端。
客户端面向接口编程,调用远程服务端对象的方法,并返回结果。
这是怎么时实现的?
查看代码的时候发现会调用到rt.jar中的对象方法,也就没法看具体实现的细节了。
http://benx.iteye.com/blog/680293
里边讲的rmi底层是基于socket的,stub在客户端发送socket,skeleton在服务端接受socket,再加上java的反射、动态代理。客户端调用接口的方法,将通过socket向服务端发送相关信息,服务端执行相应的方法,然后将执行结果返回。