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

基於Spring實現遠程服務編程

編輯:關於JAVA

一.引言

從根本上分析,Remoting實際上是一種企業分布式計算的組件。在同一服務器(Java虛擬機)內進行調用的服務(或類)並不需要把自己暴露為一種遠程服務;但是,如果你需要與一個外部程序(在不同的服務器上或在一個不同的組織中)進行通訊的話,那麼,必須把它實現為一個遠程服務。Spring框架為把業務類暴露為遠程服務提供了一種獨特而靈活的方式。

Spring Remoting架構的核心是服務對象,這些對象其實是一些POJO,也稱作Spring bean。Spring框架能夠把這些服務對象與基礎結構細節(例如它們暴露為遠程服務的方式)隔離開來;這樣以來,開發者就可以專注於實現服務對象的業務接口而不是牽涉到這些細節中去。

這個Remoting模型提供了對業務服務的遠程抽象。它負責編排和反編排方法參數並且還負責處理服務方法中拋出的任何異常—使用未檢查的RemoteAccessException異常對它們進行包裝。為了實現各種服務,Spring使用了若干設計模式。例如,它使用代理設計模式把你對HTTP POST請求的調用翻譯成指向輸出服務的URL。

本文將著重探討如何使用Spring實現一個遠程服務。也就是說,要展示使用Spring Remoting API把一個普通Java對象(POJO)轉化成一個遠程服務;這樣以來,外部程序就可以從其業務實現中調用該服務。該演示使用一個示例貸款處理應用程序把一個業務服務實現為一個遠程HTTP服務並且從一個測試客戶端調用該類中的業務方法。

二.Spring Remoting工作機制

在本節中,讓我們更為細致地分析Spring的Remoting工作機制。要把一個普通的Java類實現為一個遠程服務,需要提供如下一些內容:

1.遠程服務輸出器(exporter)—這些類用於創建為客戶端程序所調用的遠程服務端點。服務導出器還管理任何用來查詢遠程服務的注冊表。

2.代理工廠Bean—它們是用於創建代理的工廠類,客戶端能夠使用這些代理連接到遠程服務。

3.HTTP Invoker—如前面所提及,Spring HTTP Invoker使用了一種Remoting模型,你可以使用這種模型實現跨HTTP的遠程調用,同時使用Java串行化技術傳遞Java對象。這樣使得從一個普通Java類中實現一個遠程服務容易得多了,並且允許你專注於遠程服務的業務接口而不必親自考慮遠程基礎結構的實現細節。

該技術依賴於RMI Invoker的基礎結構,但是使用HTTP作為傳輸協議。

在客戶端方面,Spring HTTP Invoker提供兩種類型的客戶端:Java SE提供的標准API和Commons HttpClient API。默認情況下,它使用的是HttpClient。

接下來,讓我們看一下Spring框架所支持的遠程(Remoting)技術。

Spring框架支持的遠程技術列舉

Spring框架支持多種Remoting技術。下面,我們來對它們作逐一簡單介紹。

①遠程方法調用(RMI)

RMI是一種分布式Java技術,遠程Java對象的方法能夠從一個不同的Java虛擬機上進行調用。它基本上是遠程過程調用(RPC)的Java版本,但是,它還提供了連同相應的請求一起傳遞多個對象的能力。RMI使用真正的對象串行化來編排與反編排方法的參數而不會截斷其相應類型。

Spring以兩種方式支持RMI:傳統型RMI和使用RMI Invoker的遠程技術。

②Hessian

Hessian是一個由Caucho Technology開發的輕量級二進制RPC協議。它使用一種定制的串行化技術來實現跨網絡發送Java對象。除了對Java支持外,Hessian還提供對於例如PHP,Python,C++和C#等其它語言的實現支持。

③Burlap

Burlap是一個輕量級的用於實現Web服務的XML-RPC協議。類似Hessian,它還使用一種專利性串行化機制來實現Java對象的串行化。有關Hessian/Burlap的更多信息,恕在此不多及。

④HTTP Invoker

Spring提供一種專門的Remoting策略—HTTP Invoker,它使用標准的Java串行化機制並通過HTTP協議來暴露服務。這是一個很重要的特征,特別是當你想傳遞給服務的方法參數是復雜的類型對象而不僅是簡單的文本消息時尤為重要。

⑤EJB

Spring還支持EJB組件模型。EJB組件還提供其它的J2EE/Java EE服務,例如基於角色的認證和授權以及聲明性和編程性事務管理。然而,EJB模型是一個重量級的組件模型,所以大多數業務應用程序往往敬而遠之。

⑥Java消息服務(JMS)

JMS API是一種消息發送標准—允許Java應用程序異步地創建、發送、接收和處理消息。它提供了松耦合的和可靠的分布式通信。默認情況下,JMS Remoting使用Java串行化,但是一個JMS提供者(例如,WebLogic JMS或JBossMQ)能夠使用另外一個不同的機制(例如XStream API)以便允許通過其它技術實現消息發送。

⑦Web服務

借助於開源Web服務引擎Apache Axis並通過JAX-RPC技術,Spring為實現基於SOAP的Web服務提供支持。Web服務提供真正的平台獨立的遠程技術,但是它們的建立非常復雜,而且與常規HTTP遠程調用相比還需要額外的SOAP消息處理的開銷。因此,在不是真正需要平台獨立性的情況下,你應該盡可能避免使用Web服務。另外,你還能夠使用XFire(由Codehaus開發的一個輕量級SOAP庫)對Web服務進行暴露。

其實,每一種遠程技術都有其優點與不足,表格1對它們進行了簡單的對比。

框架 優點 缺點 RMI 全面支持Java對象串行化。因此,你能夠通過網絡發送復雜數據類型。 RMI僅是一種Java到Java型遠程方案。如果你擁有任何非Java客戶端的話,那麼你無法使用它。另外,你還無法通過HTTP協議存取對象,除非你有專門的“通道”實現RMI通訊。注意,它需要一個RMI編譯器(為了生成代理和框架)和一個外部注冊表(用於查詢服務)。 Hessian/Burlap 跨防火牆工作良好 它們使用一種專利對象串行化機制。其中,Burlap僅支持Java客戶端。它們能夠串行化Hibernate對象,但是對集合對象執行“惰式”加載。 HTTP Invoker 基於HTTP的Java到Java Remoting;通過HTTP實現Java串行化;容易建立。 服務器和客戶端應用程序都需要使用Spring。僅是一種Java方案。 EJB 支持Remoting J2EE服務,應用程序安全以及事務處理 EJB是一種重量級技術。它要求使用一個J2EE容器。 Web服務 平台和語言獨立 要付出SOAP操作所帶來的開銷,並且要求使用一個Web服務引擎。

表格1:各種Spring Remoting技術優缺點比較

如你所見,每一種Spring Remoting技術都有各自的優缺點,但是大多數實際的應用程序都會要求使用一種輕量級Remoting技術。當實現遠程服務時,使用例如EJB這樣的重量級遠程組件模型需要其它額外的開銷。通常情況下,使用一種支持對象串行化能力的HTTP服務就足夠了。

三.遠程應用程序編程舉例

現在,讓我們開始討論本文相應的示例程序。這個程序的設計目的如下:

◆基於接口的設計:一個基於接口的設計使客戶端不必了解遠程服務的實現細節;而且該實現能夠在不需要對客戶端代碼進行任何修改的情況下作出改變。

◆測試驅動開發:該應用程序中的所有組件都應該是容器外可測試的。這個示例將使用JUnit來編寫簡單的單元測試以便對你編寫代碼時產生的每一個類的設計作出驗證。

◆分層架構:一個分層的架構能夠提供松耦合、隔離及靈活性。一個典型的J2EE應用程序都會實現分層—用戶接口(UI)層,應用程序(或控制器)層,域(域模型或服務)層和基礎結構層等。本文示例應用程序中提供了控制器、服務和域三個層。

◆分離關注點:既然Remoting功能與業務服務之間毫無聯系,那麼,關注點的分離在實現服務的過程中就起著相當重要的作用。

◆輕量級服務:本文示例使用了Spring HTTP Invoker API來實現遠程服務。與其它組件模型比較,HTTP Invoker是相當輕量級的。

◆非入侵式:Spring是一個優秀的框架,非常適合於在業務應用程序中使用一種非入侵式API的情況。借助於例如Aspects和AOP等技術以及例如控制反轉(IoC),代理和工廠模式等設計模式,你可以把一項業務相關任務的實現細節封裝到服務類中並且僅對客戶端暴露接口。

除了這些目標外,該示例在設計上還遵循了一種敏捷軟件開發方法來編寫該示例應用程序所使用的類(請參考本文相應源碼)。

業務需求分析

現在,既然你知道了明確應用程序的設計目標,那麼接下來,讓我們討論實際的業務要求。這個示例應用程序是一個貸款處理系統(loanapp),顧客用它來提交應用程序以實現家庭抵押貸款。該Remoting示例的業務用例是:針對一指定的家庭財產實現水災認證檢查。每一個家庭貸款應用程序都需要一個水災認證檢查以確保財產不是位於一個水災地區。如果它位於一個水災地區,那麼要求該家庭的主人通過支付一種“813費”(813是用於標識水災認證費的代碼)來獲得相應的水災保險。

在水災地圖上,一般把高、中等或低風險地區作為“水災危險地區”,而把最高風險地區作為“特殊水災危險區域”。在高水災風險地區(AE,A或AO地區)的財產每年都有大約1%的發生水災的可能性,而對於一種達30年之久的財產抵押大約存在26%發生水災的可能性。在VE或V地區(也是高風險地區)的房地產財產每年也都有大約1%的發生水災的可能性,並且還會面臨如沿海暴風雨這樣的危險。而那些處於低級或中級水災風險地區(B或C地區)的家庭顯然是位於高風險地區之外的;盡管這些地方的水災風險會大大降低,但是卻不能被刪除。

一旦借款人完成家庭貸款應用程序並且選擇好貸款數額的相應利率,即會觸發水災認證檢查。在抵押處理的貸款處理和保險階段開始之前必須進行相應的水災情況檢查。

用例分析

下面是實現水災認證檢查用例相應的步驟:

1.顧客通過輸入細節數據(例如借款人名,屬性名稱,屬性地址,城市,郵政區碼和貸款數額)完成貸款應用程序。

2.用戶選擇一個貸款產品和利率並且在一個特定的時間周期(例如,30或45天)內鎖定此項貸款。

3.本文loanapp程序基於細節屬性(例如地址和郵政區碼)調用一個水災認證檢查。

4.基於客戶端的郵政區碼屬性,水災服務決定是否指定的屬性處於一個水災地帶以及是否它要求水災認證(這個調用是同步的;所以,在繼續貸款應用程序處理之前,客戶端需要等待服務的響應)。

5.一旦水災檢查請求返回,貸款即被提交到一個自動化保險系統(AUS)以得到該借款人的信用歷史以及該貸款應用程序的風險評價。

技術設計

根據敏捷開發過程的思想,接下來應該是對上面定義的要求進行技術設計。本示例中使用了下列設計(類和方法)來實現用例中的要求:

1.客戶端類(FloodCertClient)調用水災控制器類(FloodCertController)的requestFloodCheck()方法。

2.然後,該控制器又調用服務(FloodCertService)中的processFloodCheck()方法,通過在HTTP請求中發送貸款細節實現。

3.水災服務調用FloodDAO類來存取後端數據庫並且檢查是否指定的屬性需要進行水災認證。

4.DAO返回一個含有水災認證結果的結果對象。然後,該結果數據被返回到客戶端並顯示於Web頁面。

既然遠程服務充當進入一個企業的業務域模型的入口點,那麼把服務層作為一個整體進行設計還是很重要的。下列是在設計遠程服務時你需要牢記的一些問題:

1.遠程調用類型(遠程調用是無狀態的還是有狀態的?)

2.遠程調用激活類型(同步還是異步調用?)

3.客戶端類型(Java,.NET或一些其它類型的客戶端)

4.操作系統(Windows,Unix或另一種OS)

5.事務(你是否需要該遠程服務是事務性的以便在服務方法中實現任何數據庫或JMS隊列更新時都能夠作為一個獨立的工作單位被提交或回滾?)

為了實現此用例的所有以上要求,本文中的示例貸款處理應用程序需要使用下列技術和框架:

◆Tomcat 5.5

◆Spring 2.0

◆JUnit

◆Commons HttpClient

◆Eclipse

◆Ant

Spring配置

本文中的HTTP Invoker Remoting示例使用了兩個配置XML文件,這兩個文件中定義了相應於你編寫的實現水災遠程服務的類的Spring bean;它們分別是loanapp-servlet.xml和loanapp-client.xml。

實現

下列是基於HTTP Invoker技術針對示例貸款處理應用程序實現一個遠程服務所需的步驟:

1.創建一個HTTP Invoker服務輸出器類(HttpInvokerServiceExporter)。

2.創建一個HTTP代理(使用HttpInvokerProxyFactoryBean)。你需要在這個類中指定如serviceUrl和serviceInterface等參數。

3.定義一個URL映射,以便客戶端調用遠程HTTP服務。

4.在loanapp-servlet.xml文件中配置Spring bean。

5.在web.xml文件中配置Spring Web層(DispatcherServlet)。

6.編寫客戶端類(使用HTTP或Commons HttpClient)。

7.編寫一個JUnit測試用例來調用客戶端類中的方法。

測試

本文下載源碼文件中包含了一個JUnit測試客戶程序(FloodCertClientTest)用於測試調用水災遠程服務的客戶端類。它通過若干不同的測試貸款應用程序(使用不同的郵政區碼屬性)來調用客戶端。憑借提交的郵政區碼屬性,水災服務就能夠返回水災認證分析的結果。

四.總結

Spring遠程技術為把業務域服務暴露為遠程服務提供了一種簡單而靈活的方案。同時,它還為暴露多種協議(當然,位於不同的URL處)之下的相同服務提供了相當的靈活性。例如,你可以把本文示例程序中的水災認證檢查服務實現為一種RMI服務(對於Java客戶,應該利用更快速的Java到Java遠程技術,而對於非Java客戶則宜使用一種HTTP服務)。這樣以來,你可以僅在一處編寫業務服務邏輯,但是最終可以把該服務暴露為兩個遠程服務端點。

HTTP Invoker框架為普通Java服務接口提供了必要的代理;同時,還為把Java類實現為遠程服務提供一致的用法和配置風格。這是一種把兩個世界的實現達到最佳結合的遠程方案—把HTTP通訊的簡單性與Java內置對象串行化技術結合在一起。這使得HTTP Invoker無論對RMI還是對Hessian/Burlap都成為一種優秀的選擇。

當然,HTTP Invoker的一個重要局限性就是它僅為Spring框架所提供—這意味著,客戶端和服務應用程序都必須使用Spring框架實現。但是,當你需要一種輕量級的易於安裝而靈活的方案時,這是一種不錯的選擇。

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