1、定义一个表示远程服务的接口RemoteInterface,必须继承自java.rmi.Remote(Remote是一个标识,没有抽象的方法)。

在RemoteInterface里定义可被远程调用的方法,方法必须声明抛出java.rmi.RemoteException。


public interface RemoteInterface extends Remote {
public long serverTime() throws RemoteException;
}

2、定义一个类RemoteClass继承自UnicastRemoteObject类,且实现了远程服务接口RemoteInterface,


public class RemoteClass extends UnicastRemoteObject implements RemoteInterface {
private static final long serialVersionUID = 1L;

protected RemoteClass() throws RemoteException {
super();
}

@Override
public long serverTime() throws RemoteException {
return System.currentTimeMillis();
}

public static void main(String[] args) {
try {
RemoteClass rc = new RemoteClass();

// 创建一个远程对象注册表,并绑定到端口8985;
// 如果要绑定IP,则使用createRegistry(int port, RMIClientSocketFactory csf, RMIServerSocketFactory ssf),通过
// 在RMIClientSocketFactory、RMIServerSocketFactory的定制实现里绑定IP。
Registry registry = LocateRegistry.createRegistry(8985);

// 在rmi远程对象注册表注册一个远程对象。
registry.bind("serverTime", rc);

} catch (RemoteException e) {
e.printStackTrace();
} catch (AlreadyBoundException e) {
e.printStackTrace();
}

}

}

3、客户端查找远程对象的示例


public class ClientClass {

public static void main(String[] args) {
// 通过远程注册表查找远程对象
try {
// 获取远程注册表
Registry remoteRegistry = LocateRegistry.getRegistry("127.0.0.1", 8985);

// 从远程注册表获取远程对象
RemoteInterface remoteTime = (RemoteInterface)remoteRegistry.lookup("serverTime");

for(int i = 0; i < 10; i++) {
System.out.println("remote time :" + remoteTime.serverTime());
}

} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
// 通过远程注册表查找远程对象 end


System.out.println("================================================");

// 通过rmi协议查找远程对象
try {
// 查找远程对象
RemoteInterface remoteTime = (RemoteInterface)Naming.lookup("rmi://127.0.0.1:8985/serverTime");

for(int i = 0; i < 10; i++) {
System.out.println("remote time :" + remoteTime.serverTime());
}

} catch (MalformedURLException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
} catch (NotBoundException e) {
e.printStackTrace();
}
}

}

4、编译这些类,用rmic编译器生成根:

rmic RemoteClass

在对应的包下会出现一个文件:RemoteClass_Stub.class

5、先后运行 RemoteClass ,ClientClass ,结果大致如下:

remote time :1303288008309

remote time :1303288008309

remote time :1303288008309

remote time :1303288008309

remote time :1303288008309

remote time :1303288008309

remote time :1303288008309

remote time :1303288008309

remote time :1303288008309

remote time :1303288008309

================================================

remote time :1303288008325

remote time :1303288008325

remote time :1303288008325

remote time :1303288008325

remote time :1303288008325

remote time :1303288008325

remote time :1303288008325

remote time :1303288008325

remote time :1303288008325

remote time :1303288008325

执行远程方法调用成功。

网上找到的绑定IP的其他方法,未验证:


System.setProperty("java.rmi.server.hostname", ip);

Naming.rebind("rmi://"+serverPath + ":" + port + "/" + serverName,
serverInterface);