RMI是一種分佈式技術,使用RMI可以讓一個虛擬機上的應用程序請求調用位於網絡上另一處JVM上的對象方法。這是的以分佈式方式部署應用成爲了可能。
RMI的兩個核心所在分別爲Skeleton和Stub:
- Skeleton只在位於服務器端的程序,負責接受客戶端發來的請求數據,並交由服務器端業務處理程序處理,最後將處理結果返回給客戶端。
- Stub則負責在客戶端向服務器端發送相關數據。
開發RMI應用程序需要以下幾步:
- 定義遠程接口:繼承自java.rmi.Remote定義應用接口:IAppInterface
- 實現服務端對象:需繼承自java.rmi.UnicastRemoteObject,同時要實現已定義的接口IAppINterface中的方法
- 啓動RMI註冊服務
- 執行start rmiregistry啓動RMI註冊服務
- 啓動服務端程序,註冊到RMI註冊表中
- 開發並執行客戶端程序
在程序中執行java.rmi.registry.LocateRegistry的createRegistry(int port)方法完成RMI註冊服務的啓動。
java.rmi.registry.Registry接口提供了幾個方法來實現對RMI註冊表的訪問(類似於操作JNDI命名空間的javax.naming.Context接口)
- void bind(String name, java.rmi.Remote obj):將obj對象綁定在RMI註冊表中,鍵值爲name
- void rebind(String name, java.rmi.Remote obj):重寫鍵值爲name的RMI註冊表綁定關係,把obj綁定在RMI註冊表中,鍵值爲name
- java.rmi.Remote lookup(String name):在RMI註冊表中根據鍵值name查找對象並返回
- void unbind(String name):解除鍵值爲name的對象的RMI綁定關係
示例:
1、定義遠程接口
package org.eone.test.rmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface IWeather extends Remote{
public String getWeather(String city) throws RemoteException;
}
2、實現遠程服務
package org.eone.test.rmi;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
public class WeatherImpl extends UnicastRemoteObject implements IWeather{
public WeatherImpl() throws RemoteException{
}
public String getWeather(String city){
return city + " : is Sunny...";
}
public static void main(String[] args){
try{
Registry registry = LocateRegistry.createRegistry(1099);
registry.bind("/weather", new WeatherImpl());
System.out.println("服務對象已綁定至註冊表...");
}catch(Exception e){
System.out.println("綁定服務對象到註冊表失敗...");
}
}
}
3、開發並運行客戶端程序
package org.eone.test.rmi;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
public class WeatherClient{
public static void main(String[] args){
try{
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099);
IWeather stub = (IWeather)registry.lookup("/weather");
String result = stub.getWeather("SHANGHAI");
System.out.println(result);
}catch(Exception e){
e.printStackTrace();
}
}
}