Java遠程方法調用(Remote Method Invocation,RMI),invocationrmi
Java RMI簡介:
它是Java的一個核心API和類庫,允許一個Java虛擬機器上啟動並執行Java程式調用不同虛擬機器上啟動並執行對象中的方法,即使這兩個虛擬機器運行於物理隔離的不同主機上。
Java RMI在JDK1.1版本已經存在,是非常重要的底層技術。
下面通過一個簡單的例子來測試:
1 package com.tc.remote; 2 3 import java.rmi.Remote; 4 import java.rmi.RemoteException; 5 6 /** 7 * 一個遠程調用介面RMIQueryStatus 8 * 遠程介面必須聲明為public 9 * 遠程介面必須繼承自java.rmi.Remote10 */11 public interface RMIQueryStatus extends Remote{12 13 // 遠程調用中的方法必須拋出RemoteException異常 14 RMIFileStatus getFileStatus(String filename) throws RemoteException;15 16 }
1 package com.tc.remote; 2 3 import java.io.Serializable; 4 5 /** 6 * RMI檔案狀態類,遠程調用方法返回的對象 7 */ 8 public class RMIFileStatus implements Serializable{ 9 10 private String filename;11 12 public RMIFileStatus() {13 }14 15 public RMIFileStatus(String filename) {16 this.filename = filename;17 }18 19 @Override20 public String toString() {21 return "RMIFileStatus{" +22 "filename='" + filename + '\'' +23 '}';24 }25 26 }
1 package com.tc.remote; 2 3 import java.rmi.RemoteException; 4 import java.rmi.server.UnicastRemoteObject; 5 6 /** 7 * 遠程介面的實現 . 8 */ 9 public class RMIQueryStatusImpl extends UnicastRemoteObject implements RMIQueryStatus {10 11 /**12 * 因為UnicastRemoteObject的建構函式拋出了RemoteException異常13 * 這裡預設構造方法必須寫14 * @throws RemoteException15 */16 public RMIQueryStatusImpl() throws RemoteException {17 }18 19 @Override20 public RMIFileStatus getFileStatus(String filename) throws RemoteException {21 RMIFileStatus status = new RMIFileStatus(filename);22 // ...進行處理23 return status;24 }25 26 }
1 package com.tc.remote; 2 3 import java.net.MalformedURLException; 4 import java.rmi.Naming; 5 import java.rmi.RemoteException; 6 import java.rmi.registry.LocateRegistry; 7 8 /** 9 * 建立RMI註冊表,啟動RMI服務,並將遠程對象註冊到RMI註冊表中。10 */11 public class RMIQueryStatusServer {12 13 public static String RMI_URL = "rmi://localhost:8888/RHello";14 15 public static void main(String[] args) {16 try {17 RMIQueryStatusImpl queryStatus = new RMIQueryStatusImpl();18 // 註冊表建立19 LocateRegistry.createRegistry(8888);20 // 綁定遠端對象到名字21 Naming.rebind(RMI_URL,queryStatus);22 // Naming.bind(RMI_URL,queryStatus);23 // bind方法在已經為一個名字綁定一個對象,再向此名稱綁定對象,會拋出異常24 // 而使用rebind方法不會25 System.out.println(">>>>>INFO:遠程RMIQueryStatus對象綁定成功!");26 } catch (RemoteException e) {27 e.printStackTrace();28 } catch (MalformedURLException e) {29 e.printStackTrace();30 }31 }32 33 }
1 package com.tc.remote; 2 3 import java.net.MalformedURLException; 4 import java.rmi.Naming; 5 import java.rmi.NotBoundException; 6 import java.rmi.RemoteException; 7 8 /** 9 * 用戶端測試,在用戶端調用遠程對象上的遠程方法,並返回結果。10 */11 public class RMIQueryStatusClient {12 13 public static void main(String[] args) {14 try {15 RMIQueryStatus queryStatus = (RMIQueryStatus) Naming.lookup(RMIQueryStatusServer.RMI_URL);16 // 調用遠程方法,該調用如同調用本地方法17 RMIFileStatus status = queryStatus.getFileStatus("爆炸");18 System.out.println(status);19 } catch (NotBoundException e) {20 e.printStackTrace();21 } catch (MalformedURLException e) {22 e.printStackTrace();23 } catch (RemoteException e) {24 e.printStackTrace();25 }26 }27 28 }
先運行RMIQueryStatusServer 的main方法:
注意:雖然main方法的執行很快,但是伺服器還是會繼續啟動並執行,紅色的方塊表示了運行。
再運行RMIQueryStatusClient 的main方法:
這裡只是簡單的進行了測試,感覺Client需要拿到Server的RMI_URL,還是有比較強的依賴性。
希望實際項目中用到以後能夠有更深刻的理解。
http://docs.oracle.com/javase/8/docs/technotes/guides/rmi/index.html