亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

java語言

java遠(yuǎn)程方法調(diào)用技巧

時間:2024-09-21 06:38:02 java語言 我要投稿
  • 相關(guān)推薦

java遠(yuǎn)程方法調(diào)用技巧

  聰明出于勤奮,天才在于積累,以下是小編為大家搜索整理java遠(yuǎn)程方法調(diào)用技巧,希望能給大家?guī)韼椭?更多精彩內(nèi)容請及時關(guān)注我們應(yīng)屆畢業(yè)生考試網(wǎng)!

  概述

  Java Remote Method Invocation ( RMI -- Java遠(yuǎn)程方法調(diào)用)允許您使用Java編寫分布式對象。本文將介紹RMI的優(yōu)點以及如何將其連接到現(xiàn)有的和原有的系統(tǒng)中,以及與用Java 編寫的組件的連接。

  RMI為采用Java對象的分布式計算提供了簡單而直接的途徑。這些對象可以是新的Java對象,也可以是圍繞現(xiàn)有API的簡單的Java包裝程序。Java體現(xiàn)了“編寫一次就能在任何地方運行的模式。而RMI可將Java模式進(jìn)行擴展,使之可在任何地方運行”。

  因為RMI是以Java為核心的,所以,它將Java的安全性和可移植性等強大功能帶給了分布式計算。您可將代理和梢務(wù)邏輯等屬性移動到網(wǎng)絡(luò)中最合適的地方。如果您要擴展Java在系統(tǒng)中的使用,RMI將使您充分利用其強大功能。

  RMI可利用標(biāo)準(zhǔn)Java本機方法接口JNI與現(xiàn)有的和原有的系統(tǒng)相連接。RMI還可利用標(biāo)準(zhǔn)JDBC包與現(xiàn)有的關(guān)系數(shù)據(jù)庫連接。RMI/JNI和RMI/JDBC相結(jié)合,可幫助您利用RMI與目前使用非Java語言的現(xiàn)有服務(wù)器進(jìn)行通信,而且在您需要時可擴展Java在這些服務(wù)器上的使用。RMI可幫助您在擴展使用時充分利用Java的強大功能。

  優(yōu)點

  從最基本的角度看,RMI是Java的遠(yuǎn)程過程調(diào)用(RPC)機制。與傳統(tǒng)的RPC系統(tǒng)相比,RMI具有若干優(yōu)點,因為它是Java面向?qū)ο蠓椒ǖ囊徊糠。傳統(tǒng)的RPC系統(tǒng)采用中性語言,所以是最普通的系統(tǒng)--它們不能提供所有可能的目標(biāo)平臺所具有的功能。

  RMI以Java為核心,可與采用本機方法與現(xiàn)有系統(tǒng)相連接。這就是說,RMI可采用自然、直接和功能全面的方式為您提供分布式計算技術(shù),而這種技術(shù)可幫助您以不斷遞增和無縫的方式為整個系統(tǒng)添加Java功能。

  RMI的主要優(yōu)點如下:

  面向?qū)ο螅篟MI可將完整的對象作為參數(shù)和返回值進(jìn)行傳遞,而不僅僅是預(yù)定義的數(shù)據(jù)類型。也就是說,您可以將類似Java哈希表這樣的復(fù)雜類型作為一個參數(shù)進(jìn)行傳遞。而在目前的RPC系統(tǒng)中,您只能依靠客戶機將此類對象分解成基本數(shù)據(jù)類型,然后傳遞這些數(shù)據(jù)類型,最后在服務(wù)器端重新創(chuàng)建哈希表。RMI則不需額外的客戶程序代碼(將對象分解成基本數(shù)據(jù)類型),直接跨網(wǎng)傳遞對象。

  可移動屬性:RMI可將屬性(類實現(xiàn)程序)從客戶機移動到服務(wù)器,或者從服務(wù)器移到客戶機。例如,您可以定義一個檢查雇員開支報告的接口,以便察看雇員是否遵守了公司目前實行的政策。在開支報告創(chuàng)建后,客戶機就會從服務(wù)器端獲得實現(xiàn)該接口的對象。如果政策發(fā)生變化,服務(wù)器端就會開始返回使用了新政策的該接口的另一個實現(xiàn)程序。您不必在用戶系統(tǒng)上安裝任何新的軟件就能在客戶端檢查限制條件--從而向用戶提供爍快的反饋,并降低服務(wù)器的工作量。這樣就能具備最大的靈活性,因為政策改變時只需要您編寫一個新的Java類,并將其在服務(wù)器主機上安裝一次即可。

  設(shè)計方式:對象傳遞功能使您可以在分布式計算中充分利用面向?qū)ο蠹夹g(shù)的強大功能,如二層和三層結(jié)構(gòu)系統(tǒng)。如果您能夠傳遞屬性,那么您就可以在您的解決方案中使用面向?qū)ο蟮脑O(shè)計方式。所有面向?qū)ο蟮脑O(shè)計方式無不依靠不同的屬性來發(fā)揮功能,如果不能傳遞完整的對象--包括實現(xiàn)和類型--就會失去設(shè)計方式上所提供的優(yōu)點。

  安全:RMI使用Java內(nèi)置的安全機制保證下載執(zhí)行程序時用戶系統(tǒng)的安全。RMI使用專門為保護系統(tǒng)免遭惡意小應(yīng)用程序侵害而設(shè)計的安全管理程序,可保護您的系統(tǒng)和網(wǎng)絡(luò)免遭潛在的惡意下載程序的破壞。在情況嚴(yán)重時,服務(wù)器可拒絕下載任何執(zhí)行程序。

  便于編寫和使用:RMI使得Java遠(yuǎn)程服務(wù)程序和訪問這些服務(wù)程序的Java客戶程序的編寫工作變得輕松、簡單。遠(yuǎn)程接口實際上就是Java接口。服務(wù)程序大約用三行指令宣布本身是服務(wù)程序,其它方面則與任何其它Java對象類似。這種簡單方法便于快速編寫完整的分布式對象系統(tǒng)的服務(wù)程序,并快速地制做軟件的原型和早期版本,以便于進(jìn)行測試和評估。因為RMI程序編寫簡單,所以維護也簡單。

  可連接現(xiàn)有/原有的系統(tǒng):RMI可通過Java的本機方法接口JNI與現(xiàn)有系統(tǒng)進(jìn)行進(jìn)行交互。利用RMI和JNI,您就能用Java語言編寫客戶端程序,還能使用現(xiàn)有的服務(wù)器端程序。在使用RMI/JNI與現(xiàn)有服務(wù)器連接時,您可以有選擇地用Java重新編寫服務(wù)程序的任何部分,并使新的程序充分發(fā)揮Java的功能。類似地,RMI可利用JDBC、在不修改使用數(shù)據(jù)庫的現(xiàn)有非Java源代碼的前提下與現(xiàn)有關(guān)系數(shù)據(jù)庫進(jìn)行交互。

  編寫一次,到處運行:RMI是Java“編寫一次,到處運行 ”方法的一部分。任何基于RMI的系統(tǒng)均可100%地移植到任何Java虛擬機上,RMI/JDBC系統(tǒng)也不例外。如果使用RMI/JNI與現(xiàn)有系統(tǒng)進(jìn)行交互工作,則采用JNI編寫的代碼可與任何Java虛擬機進(jìn)行編譯、運行。

  分布式垃圾收集:RMI采用其分布式垃圾收集功能收集不再被網(wǎng)絡(luò)中任何客戶程序所引用的遠(yuǎn)程服務(wù)對象。與Java 虛擬機內(nèi)部的垃圾收集類似,分布式垃圾收集功能允許用戶根據(jù)自己的需要定義服務(wù)器對象,并且明確這些對象在不再被客戶機引用時會被刪除。

  并行計算:RMI采用多線程處理方法,可使您的服務(wù)器利用這些Java線程更好地并行處理客戶端的請求。Java分布式計算解決方案:RMI從JDK 1.1開始就是Java平臺的核心部分,因此,它存在于任何一臺1.1 Java虛擬機中。所有RMI系統(tǒng)均采用相同的公開協(xié)議,所以,所有Java 系統(tǒng)均可直接相互對話,而不必事先對協(xié)議進(jìn)行轉(zhuǎn)換。

  傳遞屬性

  前面我們講到,RMI可以傳遞屬性,并簡單介紹了一下一個有關(guān)開支報告程序的情況。下面我們將深入討論如何設(shè)計這樣的系統(tǒng)。這樣介紹的目的是使您能夠利用RMI的功能將屬性從一個系統(tǒng)傳遞到另一個系統(tǒng),并隨心所欲地安排當(dāng)前的計算地點,并便于將來的改變。下面的例子并未涉及真實世界可能發(fā)生的所有問題,但可幫助讀者了解處理問題的方法。

  服務(wù)器定義的策略

  圖1是可進(jìn)行動態(tài)配置的開支報告系統(tǒng)的示意圖?蛻魴C向用戶顯示圖形用戶界面(GUI),用戶填寫開支報告?蛻魴C程序使用RMI與服務(wù)器進(jìn)行通信。服務(wù)器使用JDBC( Java關(guān)系數(shù)據(jù)庫連接包)將開支報告存儲在數(shù)據(jù)庫中。至此,這看起來與其它多層次系統(tǒng)大同小異,但有一個重大區(qū)別-- RMI能下載屬性。

  假定公司關(guān)于開支報告的政策發(fā)生改變。例如,目前公司只要求對超過20美元的開支需開具發(fā)票。但到明天,公司認(rèn)為這太寬松了,便決定除不超過20美元的餐費以外,任何開支均需開具發(fā)票。如果不能下載屬性的話,那么在設(shè)計便于修改的系統(tǒng)時您可選擇下列方法之一:

  用客戶端安裝與政策有關(guān)的程序。政策改變時,必須更新包含此政策的所有客戶端程序。您可在若干服務(wù)器上安裝客戶程序,并要求所有用戶從這些服務(wù)器之一運行客戶程序,從而減少問題。但這仍不能徹底解決問題-- 那些讓程序運行好幾天的用戶就無法使程序更新,而總是會有一些用戶為了方便而把軟件復(fù)制到本地磁盤上。

  您可要求服務(wù)器在每次向開支報告添加項目時檢查政策。但這樣就會在客戶機和服務(wù)器之間產(chǎn)生大量數(shù)據(jù)流,并增加服務(wù)器的工作量。這還會使系統(tǒng)變得更加脆弱--網(wǎng)絡(luò)故障會立即妨礙用戶,而不僅僅是只在其呈交開支報告或啟動新的報告時對其產(chǎn)生影響。同時,添加項目的速度也會變慢,因為這需要穿越整個網(wǎng)絡(luò)往返一圈才能到達(dá)(不堪重負(fù)的)服務(wù)器。

  您可在呈交報告時要求服務(wù)器對政策進(jìn)行檢查。這樣就會使用戶創(chuàng)建很多必須待批報告的錯誤項目,而不是立刻捕捉到第一個錯誤,從而使用戶有機會停止制造錯誤。為避免浪費時間,用戶需要立刻得到有關(guān)錯誤的反饋。

  有了RMI,您就能以簡單的方法調(diào)用程序從服務(wù)器得到屬性,從而提供了一種靈活的方式,將計算任務(wù)從服務(wù)器卸載到客戶機上,同時為用戶提供速度更快的反饋。當(dāng)用戶準(zhǔn)備編寫一份新的開支報告時,客戶機就會向服務(wù)器要求一個對象,該對象嵌入了適用于該開支報告的當(dāng)前政策,就如同通過用Java編寫的政策接口所表示的那樣。該對象可以以任何方式實現(xiàn)當(dāng)前政策。如果這是客戶機RMI首次看到這種專門執(zhí)行的政策,就會要求服務(wù)器提供一份執(zhí)行過程的副本。如果執(zhí)行過程將來發(fā)生變化,則一種新的政策對象將被返回給客戶機,而RMI運行時則會要求得到新的執(zhí)行過程。

  這表明,政策永遠(yuǎn)是動態(tài)的。您要想修改政策,就只需簡單地編寫通用政策接口的新的執(zhí)行程序,把它安裝在服務(wù)器上,并對服務(wù)器進(jìn)行配置以返回這種新類型的對象即可。這樣,每臺客戶機都會根據(jù)新的政策對新的開支報告進(jìn)行檢查。

  這是一種比任何靜態(tài)方法都更好的方法,原因如下:

  所有客戶機不必暫;蛴眯碌能浖䜩砩--軟件可根據(jù)需要在不工作時加以更新。

  服務(wù)器不必參與項目檢查工作,該工作可在本地完成。

  允許動態(tài)限制,因為對象執(zhí)行程序(而不僅僅是數(shù)據(jù))是在客戶機和服務(wù)器之間進(jìn)行傳遞的。

  使用戶能立刻看到錯誤。

  使客戶機在服務(wù)器上所能調(diào)用的方法的遠(yuǎn)程接口定義如下:

  import java.rmi.*;

  public interface ExpenseServer extends Remote {

  Policy getPolicy() throws RemoteException;

  void submitReport(ExpenseReport report)

  throws RemoteException, InvalidReportException;

  }

  import語句輸入Java RMI包。所有RMI類型均在包java.rmi或其子包內(nèi)定義。接口ExpenseServer是一般的Java接口,具有如下兩種有趣的特點:

  它擴展了名為Remote的RMI接口,這使該接口標(biāo)記為可用于遠(yuǎn)程調(diào)用。

  它的所有方法均拋出RemoteException,后者用來表示網(wǎng)絡(luò)或信息故障。

  遠(yuǎn)程方法還可拋出您所需要的任何其他例外,但至少必須拋出RemoteException,這樣您才能處理只會在分布式系統(tǒng)中發(fā)生的錯誤狀態(tài)。該接口本身支持兩個方法:getPolicy (返回一個實現(xiàn)政策接口的對象),和submitReport (提交一個完成的開支請求,并在報告無論因何種原因使表格出現(xiàn)錯誤時,拋出一個例外)。

  政策接口本身可聲明一種使客戶機知道能否在開支報告中添加一個項目的方法:

  public interface Policy {

  void checkValid (Expenseentry entry)

  throws PolicyViolationException;

  }

  如果該項目有效--即符合當(dāng)前政策,則該方法可正常返回。否則就會拋出一個描述該錯誤的例外。政策接口是本地的(而非遠(yuǎn)程的),所以將通過本機對象在客戶機上執(zhí)行--在客戶機的虛擬機上,而非整個網(wǎng)絡(luò)上運行的對象?蛻魴C可能運行下列程序:

  Policy curPolicy = server.getPolicy();

  start a new expense report

  show the GUI to the user

  while (user keeps adding entries) {

  try {

  curPolicy.checkValid(entry); // throws exception if not OK

  add the entry to the expense report

  } catch (PolicyViolationException e) {

  show the error to the user

  }

  }

  server.submitReport(report);

  當(dāng)用戶請求客戶機軟件啟動一份新的開支報告時,客戶機就調(diào)用server.getPolicy,并要求服務(wù)器返回一個包含當(dāng)前開支政策的對象。添加的每個項目首先都被提交給該政策對象,以獲得批準(zhǔn)。如果政策對象報告無錯誤,則該項目就被添加到報告中;否則錯誤就被顯示給用戶,而后者可采取修正措施。當(dāng)用戶完成向報告中添加項目時,整個報告就被呈交。服務(wù)程序如下:

  import java.rmi. *;

  import java.rmi.server. *;

  class ExpenseServerImpl

  extends UnicastRemoteObject

  implements ExpenseServer

  {

  ExpenseServerImpl() throws RemoteException {

  // . . . set up server state . . .

  }

  public Policy getPolicy() {

  return new TodaysPolicy();

  }

  public void submitReport(ExpenseReport report) {

  // . . . write the report into the db . . .

  }

  }

  除基本程序包外,我們還輸入RMI的服務(wù)程序包。類型UnicastRemoteObject 定義了此服務(wù)程序遠(yuǎn)程對象的類型,在本例中,應(yīng)為單一服務(wù)程序而非復(fù)制服務(wù)(下面還會詳細(xì)介紹)。Java類ExpenseSeverImpl實現(xiàn)遠(yuǎn)程接ExpenseServer的方法。遠(yuǎn)程主機的客戶機可使用RMI將信息發(fā)送給ExpenseServerImpl對象。

  本文中討論的重要方法是getPolicy,它簡單地返回定義當(dāng)前政策的對象。下面看一個執(zhí)行政策的例子:

  public class TodaysPolicy implements Policy {

  public void checkValid(ExpenseEntry entry)

  throws PolicyViolationException

  {

  if (entry.dollars() < 20) {

  return; // no receipt required

  else if (entry.haveReceipt() == false) {

  throw new PolicyViolationException;

  }

  }

  }

  TodaysPolicy進(jìn)行檢查的目的是確保無收據(jù)的任何項目均少于20美元。如果將來政策發(fā)生變化,僅少于20美元的餐費可不受“需要收據(jù)”政策的限制,則您可提供新的政策實現(xiàn):

  public class TomorrowsPolicy implements Policy {

  public void checkValid(ExpenseEntry entry)

  throws PolicyViolationException

  {

  if (entry.isMeal() && entry.dollars() < 20) {

  return; // no receipt required

  } else if (entry.haveReceipt() == false) {

  throw new PolicyViolationException;

  }

  }

  }

  編寫這個類,并把它安裝在服務(wù)器上,然后告訴服務(wù)器開始提供TomorrowsPolicy對象,而非daysPolicy對象,這樣您的整個系統(tǒng)就會開始使用新的政策。當(dāng)客戶機調(diào)用服務(wù)器的getPolicy方法時,客戶機的RMI就會檢查返回的對象是否為已知類型。每臺客戶機首次遇到TomorrowsPolicy時,RMI就會在getPolicy返回前下載政策的實現(xiàn)?蛻魴C可輕松地開始增強這個新的政策。

  RMI使用標(biāo)準(zhǔn)Java對象序列化機制傳遞對象。引用遠(yuǎn)程對象參數(shù)作為遠(yuǎn)程引用傳遞。如果向某方法提供的參數(shù)為原始類型或本機(非遠(yuǎn)程)對象,則向服務(wù)器傳遞一個深副本。返回值也拾照同樣的方式處理,只不過是沿其它方向。RMI可使用戶向本機對象傳遞和返回完整對象圖并為遠(yuǎn)程對象傳遞和返回引用。

  在真實的系統(tǒng)中,getPolicy方法可能會有一個可以識別用戶及開支報告類型(差旅、客戶關(guān)系等)的參數(shù),這樣可使政策加以區(qū)別。您或者可以不要求單獨的政策和開支報告對象,但您可以有一種newExpenseReport方法,它可返回一個直接檢查政策的ExpenseReport對象。這最后一種策略可使您像修改政策一樣簡單地修改開支報告的內(nèi)容--當(dāng)公司決定需要把餐費劃分為早餐、午餐和晚餐項目,而且像上述修改政策一樣簡單地執(zhí)行修改時--可編寫一個實現(xiàn)該報告的新類,客戶程序就會自動使用這個類。

  計算服務(wù)器

  開支報告的例子表示了客戶機如何從服務(wù)器得到屬性。屬性可沿兩個方向傳遞--客戶機也可將新的類型傳遞給用戶。最簡單的例子就是如圖2所示的計算服務(wù)器,該服務(wù)程序可執(zhí)行任意任務(wù),這樣整個企業(yè)內(nèi)的客戶機都能利用高端或?qū)S糜嬎銠C。

  任務(wù)由一個簡單的本地(非遠(yuǎn)程)接口定義:

  public interface Task {

  Object run();

  }

  運行時,它就會進(jìn)行一些計算,并返回一個包含結(jié)果的對象。這完全是一般性的任務(wù)--幾乎所有計算任務(wù)都可在這個接口下實現(xiàn)。遠(yuǎn)程接口ComputeServer也同樣簡單:

  import java.rmi.*;

  public interface ComputeServer extends Remote {

  Object compute(Task task) throws RemoteException;

  }

  這個遠(yuǎn)程接口的唯一目的就是使客戶機創(chuàng)建一個Task (任務(wù))對象,并把它發(fā)送給服務(wù)器執(zhí)行,最后返回結(jié)果。該服務(wù)器的基本實現(xiàn)如下:

  import java.rmi.*;

  import java.rmi.server.*;

  public class ComputeServerImpl

  extends UnicastRemoteObject

  implements ComputeServer

  {

  public ComputeServerImpl() throws RemoteException { }

  public Object compute(Task task) {

  return task.run();

  }

  public static void main(String[] args) throws Exception {

  // use the default, restrictive security manager

  System.setSecurityManager(new RMISecurityManager());

  ComputeServerImpl server = new ComputeServerImpl();

  Naming.rebind("ComputeServer", server);

  System.out.println("Ready to receive tasks");

  return;

  }

  }

  如果您看一看compute方法就會發(fā)現(xiàn),它非常簡單。它只是接受傳遞給它的對象,并返回計算的結(jié)果。main方法包括服務(wù)器的啟動代碼--它安裝了RMI的缺省安全管理程序,以防止他人存取本地系統(tǒng),并創(chuàng)建可處理進(jìn)入的請求的ComputeServerImpl對象,并將其與名字"ComputeServer"關(guān)聯(lián)。這時,服務(wù)器已經(jīng)準(zhǔn)備好接收要執(zhí)行的任務(wù),而main 也完成了其設(shè)置。

  如上所述,這實際上是一種全面和實用的服務(wù)。系統(tǒng)可以得到改進(jìn),比如,可添加要計算的參數(shù),從而對使用服務(wù)程序的部門進(jìn)行計費。但在很多情況下,上述接口和及其實現(xiàn)允許使用高端計算機進(jìn)行遠(yuǎn)程計算。這又明了RMI的簡單性--如果您鍵入上述類,對其進(jìn)行編譯,并啟動服務(wù)程序,您就擁有了能執(zhí)行任意任務(wù)的運行計算服務(wù)器。

  下面介紹一個使用這種計算服務(wù)的例子。假定您購買了一個能運行大量計算操作應(yīng)用程序的非常高端的系統(tǒng)。管理員可在該系統(tǒng)上啟動一個Java虛擬機,運行ComputeServerImpl對象。該對象現(xiàn)在就可接受要運行的任務(wù)。

  現(xiàn)在假定一個小組準(zhǔn)備通過一組數(shù)據(jù)培訓(xùn)一個神經(jīng)網(wǎng)絡(luò),以幫助制訂采購策略。他們可以采用的步驟如下:

  定義一個類--暫且稱之為PurchaseNet。它能接受一組數(shù)據(jù),并運行培訓(xùn)數(shù)據(jù),返回一個經(jīng)過培訓(xùn)的神經(jīng)網(wǎng)絡(luò)。PurchaseNet 將實現(xiàn)Task (任務(wù))接口,并在其run方法中執(zhí)行其工作。他們可能還需要一個Neuron類來描述所返回的網(wǎng)絡(luò)中的節(jié)點,而且很可能需要其它類來描述處理過程。run方法將返回一個由一組經(jīng)過培訓(xùn)的Neuron對象組成的NeuralNet對象。

  當(dāng)這些類被編寫好并進(jìn)行小規(guī)模測試時,用一個PurchaseNet 對象調(diào)用ComputeServer的compute方法。

  當(dāng)ComputeServerImpl對象中的RMI系統(tǒng)接收到作為進(jìn)入?yún)?shù)的 PurchaseNet對象時,它就下載PurchaseNet的實現(xiàn),并調(diào)用該服務(wù)器的compute方法,并把該對象作為Task (任務(wù))參數(shù)。

  Task,也就是PurchaseNet對象,將開始執(zhí)行其執(zhí)行程序。當(dāng)執(zhí)行程序需要諸如Neuron和NeuralNet等新的類時,它們可根據(jù)需要下載。

  所有計算都將在計算服務(wù)器上執(zhí)行,而客戶機線程則等待結(jié)果。(客戶機系統(tǒng)上的另一個線程則會顯示“正在等待”光標(biāo)或使用Java的內(nèi)置并行機制執(zhí)行另一個任務(wù) )。當(dāng)運行返回其NeuralNet對象時,這個對象將作為compute 方法的結(jié)果被傳遞回客戶機。

  這不需要在服務(wù)器上安裝其它軟件--所有必須完成的任務(wù)都由各部門在其自己的計算機上完成,隨后再根據(jù)需要傳遞給計算服務(wù)器主機。

  這個簡單的計算服務(wù)器體系結(jié)構(gòu)為系統(tǒng)的分布式功能提供了功能強大的轉(zhuǎn)換能力。一項任務(wù)的計算可以被轉(zhuǎn)移到一個能為其提供最好支持的系統(tǒng)上完成。這樣的系統(tǒng)可以被用來:

  在ComputeServerImpl對象運行于有數(shù)據(jù)挖掘需要的主機上,支持?jǐn)?shù)據(jù)挖掘應(yīng)用程序。這樣可使您輕松地把任何計算移動到數(shù)據(jù)所在的地方。

  在從當(dāng)前股票價格、發(fā)貨信息或其它實時信息等外部資源獲得直接數(shù)據(jù)的服務(wù)器上運行計算任務(wù)。

  通過運行ComputeServer (接受進(jìn)入的請求并將其轉(zhuǎn)送到運行 ComputeServerImpl的負(fù)擔(dān)最小的服務(wù)器上)的不同實現(xiàn),而將任務(wù)分布在多個服務(wù)器上。

  代理

  因為RMI允許使用Java實現(xiàn)下載屬性,所以您可使用RMI 編寫代理系統(tǒng)。代理的最簡單格式如下:

  import java.rmi.*;

  public interface AgentServer extends Remote {

  void accept(Agent agent)

  throws RemoteException, InvalidAgentException;

  }

  public interface Agent extends java.io.Serializable {

  void run();

  }

  啟動一個代理也就創(chuàng)建了實現(xiàn)Agent (代理)接口、找到服務(wù)器、激活接受該代理對象的類。該代理的執(zhí)行程序?qū)⒈幌螺d到服務(wù)器上運行。accept方法將啟動一個該代理的新線程,激活其run方法,然后返回,從而使該代理一直執(zhí)行到run方法返回為止。代理可通過激活在另一臺主機上運行的服務(wù)程序的accept方法而移植到該主機,而其本身則作為將被接受的代理來傳遞,并結(jié)束其在原來主機上的線程。

  面向?qū)ο蟮拇a重用與設(shè)計模式

  面向?qū)ο蟮木幊淌且豁椩试S代碼重用的強大技術(shù)。很多企業(yè)組織都使用面向?qū)ο蟮木幊虂頊p輕創(chuàng)建程序的負(fù)擔(dān)和提高系統(tǒng)的靈活性。RMI是完全面向?qū)ο蟮?-信息被發(fā)送給遠(yuǎn)程對象,而且對象可以被傳遞和返回。

  Design Patterns (設(shè)計模式)目前在描述面向?qū)ο笤O(shè)計的實踐活動中獲得了相當(dāng)大的成功。首先是因為Design Patterns 的創(chuàng)新工作而使之大受歡迎,這些編程方式是一種正式描述解決某類特定問題的完整方法的途徑。所有這些設(shè)計模式都依賴于創(chuàng)建一個或多個抽象概念,這些抽象概念允許不同的實現(xiàn),從而允許和增強軟件重用。軟件重用是面向?qū)ο蠹夹g(shù)的主要優(yōu)勢,而設(shè)計模式則是促進(jìn)重用的最受歡迎的技術(shù)之一。

  所有設(shè)計模式都依賴面向?qū)ο蟮亩鄳B(tài)性--這是對象( 如Task )擁有多個實現(xiàn)的能力。算法的普通部分(如compute 方法)不必知道使用了哪個實現(xiàn),它只需知道得到一個對象后應(yīng)該對該對象采取什么操作。特別地,計算服務(wù)器就是Command (指令)模式的一個例子,它可使您將請求 (任務(wù))表示為對象,并對其進(jìn)行調(diào)度。

  只有當(dāng)包括執(zhí)行程序在內(nèi)的完整對象能在客戶機和服務(wù)器之間傳遞時,才會存在這樣的多態(tài)性。DCE和DCOM等傳統(tǒng)的RPC系統(tǒng)以及CORBA等基于對象的RPC系統(tǒng)不能下載并執(zhí)行程序,因為它們不能把真實對象作為參數(shù)傳遞,而只能傳遞數(shù)據(jù)。

  RMI可傳遞包括執(zhí)行程序在內(nèi)的所有類型,所以您可以在分布式計算解決方案中,而不僅僅是本地計算中使用面向?qū)ο蟮木幊?-包括設(shè)計方式。如果沒有RMI這樣完全面向?qū)ο蟮南到y(tǒng),那么您就必須放棄很多分布式計算系統(tǒng)中的設(shè)計方式--以及面向?qū)ο蟮能浖赜玫钠渌问健?/p>

【java遠(yuǎn)程方法調(diào)用技巧】相關(guān)文章:

Java遠(yuǎn)程方法調(diào)用RMI03-18

java構(gòu)造函數(shù)調(diào)用技巧03-27

Java程序調(diào)用C/C++語言函數(shù)的方法12-01

java調(diào)用c函數(shù)的實例04-03

Think in Java之構(gòu)造器的真正調(diào)用順12-01

Java中傳值調(diào)用的理解和透析04-03

C++調(diào)用C函數(shù)的方法11-15

PHP編程:類和對象、方法調(diào)用11-27

Java語言的學(xué)習(xí)技巧11-27