程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 用RMI實現基於Java的分布式計算

用RMI實現基於Java的分布式計算

編輯:關於JAVA

Java 2 Enterprise Edition(J2EE)遠程方法調用(Remote Method Invocation,RMI)框架允許你創建透明的、分布式的服務和應用程序。基於RMI的應用程序由Java對象構成,這些對象相互調用,同時忽略對方的位置。換言之,一個Java對象可調用另一個虛擬機上的某個Java對象的方法,整個過程和調用同一個虛擬機上的某個Java對象的方法無異。

駐留在不同虛擬機上的對象為了相互獲得引用,可以使用RMI的查找服務,或者將對象引用作為方法調用的一個參數或者返回值來接收。參數和返回值借助Java的對象序列化機制由RMI來進行封送。

遠程對象和接口

Java提供了一個完全限定名稱為java.rmi.Remote的接口。任何對象要想參與和另一個Java對象的遠程會話,就必須直接或間接地實現該接口。尤其要注意的是,任何由java.rmi.Remote接口來標識的對象都暗示著它的方法可從其他任何虛擬機進行調用。實現了Java.rmi.Remote接口的對象通常稱為“遠程對象”,必須采用以下方式來聲明它的方法:

每個支持遠程調用的方法都必須在其throws子句中聲明Java.rmi.RemoteException。

對於一個可遠程調用的方法,它的每個非基本(nonprimitive)參數或者返回值都必須直接或間接地聲明為實現了Java.io.Serializable接口。

除了實現java.rmi.Remote接口和正確聲明任何遠程方法之外,遠程對象必須提供一個無參數的構造函數,它能引發一個Java.rmi.RemoteException異常。這就保證了對象可基於一種序列化狀態來遠程構造。

遠程對象必須導出,以接收傳入的遠程方法調用。為此,你通常需要擴展java.rmi.server.UnicastRemoteObject或者Java.rmi.activation.Activatable。通過對其中任何一個類進行擴展,遠程對象就可在創建時自動導出。

以下接口定義展示了Java.rmi.Remote接口最典型的用法:

import Java.rmi.Remote;

import Java.rmi.RemoteException;

public interface TimeKeeper extends Remote

{

 public String currentDate() throws RemoteException;

 public String currentTime() throws RemoteException;

}

由於String類聲明為實現了Java.io.Serializable接口,所以String是遠程方法的有效返回類型。

以下代碼展示了如何實現TimeKeeper接口,以便定義一個有效的遠程對象:

import Java.rmi.RemoteException;

import Java.util.Calendar;

import Java.util.GregorianCalendar;

public class TimeKeeperImpl implements TimeKeeper

{

 public TimeKeeperImpl()

 throws RemoteException

 {

 }

 public String currentDate() throws RemoteException

 {

 Calendar cal = new GregorianCalendar();

 String retVal = (cal.get(Calendar.MONTH) + "/" +

 cal.get(Calendar.DAY_OF_MONTH) + "/" +

 cal.get(Calendar.YEAR));

 return retVal;

 }

 public String currentTime() throws RemoteException

 {

 Calendar cal = new GregorianCalendar();

 String retVal = (cal.get(Calendar.HOUR_OF_DAY) + ":" +

 cal.get(Calendar.MINUTE) + ":" +

 cal.get(Calendar.SECOND));

 return retVal;

 }

}

RMI注冊表

為了獲取對遠程對象的引用,RMI提供了名為注冊表(registry)的一個遠程對象,它將名稱與遠程對象關聯起來。RMI服務器要向注冊表注冊每一個遠程對象,以便定位和檢索對象。RMI客戶端希望調用遠程對象上的一個方法時,首先必須根據遠程對象的名稱在注冊表中定位遠程對象。如果遠程對象存在,注冊表就返回對那個對象的一個引用。然後,要使用這個引用來發出對遠程對象的方法調用。

RMI服務器

RMI采取一種客戶機/服務器結構進行通信。這意味著在RMI會話的某一端,必須有一個對象充當服務器,另一端的對象則充當客戶端。RMI服務器負責創建每個遠程對象的實例,並將每個實例和RMI注冊表中的一個名稱綁定起來。RMI服務器可以自主,這要求它實現一個main方法,避免必須依賴其他類才能執行。

由於RMI服務器可從幾乎任何主機下載和執行代碼,所以每個RMI服務器的main方法都需要安裝一個安全管理器,防止它所加載的類表現失常。下例展示了如何實例化一個安全管理器,以及如何在RMI注冊表中綁定一個對象實例:

import Java.rmi.RMISecurityManager;

import Java.rmi.Naming;

public class SimpleRMIServer

{

 public static void main(String[] args)

 {

 if (System.getSecurityManager() == null)

 {

 System.setSecurityManager(new RMISecurityManager());

 }

 try

 {

 TimeKeeperImplremoteObj = new TimeKeeperImpl();

 // Bind the remote object to the name "TimeKeeper"

 Naming.bind("//HostName/TimeKeeper", remoteObj);

 System.out.println("TimeKeeper successfully bound in registry");

 }

 catch (Exception e)

 {

 System.err.println("Error binding TimeKeeper: " + e.getMessage());

 }

 }

}

小結

本文簡單介紹了如何用RMI來隱藏遠程交互問題,使程序員能將注意力集中在其他更重要的問題上,而不必過多地考慮通信基礎結構。下一篇文章將進一步探索RMI,講解RMI客戶端如何定位遠程對象,並調用其上的方法。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved