• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 使用IoC和AOP重構SOA應用(1)

    發表于:2007-06-13來源:作者:點擊數: 標簽:
    1.引言 SOA是一種構造分布式系統的方法,它將業務應用功能以服務的形式提供出來,以便更好的復用、組裝和與外部系統集成,從而降低 開發 成本,提高開發效率。SOA的目標是為企業構建一個靈活,可擴展的IT基礎架構來更好地支持隨需應變的商務應用。 隨著SOA技

    1.引言

    SOA是一種構造分布式系統的方法,它將業務應用功能以服務的形式提供出來,以便更好的復用、組裝和與外部系統集成,從而降低開發成本,提高開發效率。SOA的目標是為企業構建一個靈活,可擴展的IT基礎架構來更好地支持隨需應變的商務應用。

    隨著SOA技術和產品的不斷成熟,現在越來越多的用戶開始了解并認同SOA的理念,但對SOA項目的實施還缺乏信心。其主要原因是:SOA應用開發還相對比較復雜。

    一年多來,本文作者所在的部門已經從事了許多國內外的SOA項目的實施和支持工作,積累了許多SOA應用開發經驗。我們希望能夠通過一系列的文章與讀者分享這些想法,幫助您更好地構建SOA應用。

    本文將從Web Service調用入手,在解決一系列具體問題的過程中,使用IoC (Inversion of Control) 和AOP (Aspect- Oriented Programming) 等方法重構Web Service的訪問代碼,使得業務邏輯與Web Service訪問解耦,為您提供一個更加靈活和易于擴展的訪問模式。

    Spring是一個流行的輕量級容器,對IoC和AOP提供了良好的支持。本文為您提供了一個基于Spring的實現供您下載學習。示例代碼工程使用Eclipse3.1/3.02和JDK1.4開發, 您還需要Spring 1.2.5和Axis1.3提供的支持。源碼下載。

    2.Web Service調用

    Web Service是目前實現SOA應用的一項基本的,適用的技術,它為服務的訪問提供了一個被廣泛接受的開放標準。為了便于說明問題,我們將使用XMethods 網站(http://www.xmethods.net/)發布的貨幣兌換服務作為示例。并針對JAX-RPC 1.1,說明如何編寫Web Service 的調用代碼。

    2.1 示例說明

    http://xmethods.net 作為最早推出Web Service實際示例的網站,提供了很多優秀的Web Service 樣例。其中有一個匯率計算服務,可以返回兩個國家之間的貨幣兌換比例。獲取該服務的詳細信息,請參考該服務的服務描述文檔(獲取WSDL 文檔) 。在此就不具體解析該服務描述文檔了。讀者可以從WSDL2Java生成的接口中了解該服務的用法:

    public interface CurrencyExchangePortType extends java.rmi.Remote {

    public float getRate(String country1, String country2) throws java.rmi.RemoteException;

    }

    2.2 客戶端調用方法

    JAX-RPC作為Java平臺的RPC服務調用標準接口,為Web Service客戶端調用提供了3種方法,分別是DII,動態代理,和靜態Stub。 DII(Dynamic Invocation Interface)采用直接調用方式,可以在程序中設置諸多的調用屬性,使用較為靈活,但是調用過程卻相對繁瑣復雜,易造成代碼膨脹且可重用性低,每次調用不同的Web Service都要重復進行大量編碼。

    JAX-RPC中動態代理(Dynamic Proxy)的方法實現對Web Service的動態調用,可以在運行時根據用戶定義的Client端接口創建適配對象。從而避免了直接操作底層的接口,減少了客戶端的冗余,屏蔽了調用相關的復雜性。

    使用靜態Stub和Service Locator是目前最常用的調用方式。JAX-RPC使用靜態的Stub方式包裝對底層接口的調用,從而提供一種更為簡便的調用方式。使用該方式需要利用支持環境(比如Axis)所提供的工具根據WSDL預生成Web Service客戶端的實現代碼。因此如果服務的WSDL發生變化,就必須重新生成新的客戶端代碼并進行重新部署。

    為了更詳細的了解靜態Stub的調用方式,您可以將示例代碼的WebServiceClient.jar導入到您現有Eclipse工作區之中。

    客戶端生成代碼包括如下4個類:如圖 1 所示:

    圖 1: 客戶端代碼類圖

    在上圖中包括的幾個類中:

    • CurrencyExchangePortType:服務端點接口,定義了Web Service的方法簽名。
    • CurrencyExchangeService:Service接口,定義了獲取服務端點接口的方法。
    • CurrencyExchangeServiceLocator:ServiceLocator類,實現了Service接口。
    • CurrencyExchangeBindingStub: Stub實現類,實現了服務端點接口,封裝了對Web Service訪問的底層邏輯。

    使用Stub調用Web Service的過程也非常簡單,讀者可以參考清單 1:

    清單 1:Web Service 調用代碼示例

    try {

    //創建ServiceLocator

    CurrencyExchangeServiceLocator locator = new

    CurrencyExchangeServiceLocator();

    //設定端點地址

    URL endPointAddress = new URL("http://services.xmethods.net:80/soap");

    //創建Stub實例

    CurrencyExchangePortType stub =

    locator.getCurrencyExchangePort(endPointAddress);

    //設定超時為120秒

    ((CurrencyExchangeBindingStub)stub).setTimeout(120000);

    //調用Web Service計算人民幣與美元的匯率

    float newPrice = stub.getRate("China", "USA") * 100;

    } catch (MalformedURLException mex) {

    //...

    } catch (ServiceException sex) {

    //...

    } catch (RemoteException rex) {

    //...

    }

    3.重構Web Service調用代碼

    3.1 實例代碼中的"壞味道"

    上面的基于Service Locator的Web Service訪問代碼雖然簡單但暴露出以下幾個問題:

    1.訪問Web Service所需的配置代碼被嵌入應用邏輯之中

    在Web Service調用中,我們需要設定一系列必要的參數。比如:服務端點地址、用戶名/密碼、超時設定等等。這些參數在開發和運行環境中都有可能發生變化。我們必須提供一種機制:在環境變化時,不必修改源代碼就可以改變Web Service的訪問配置。

    2 客戶端代碼與Web Service訪問代碼綁定

    在上面的代碼中,業務邏輯與Web Service的Stub創建和配置代碼綁定在一起。這也不是一種良好的編程方式??蛻舳舜a只應關心服務的接口,而不應關心服務的實現和訪問細節。比如,我們既可以通過Web Service的方式訪問遠程服務,也可以通過EJB的方式進行訪問。訪問方式對業務邏輯應該是透明的。

    這種分離客戶端代碼與服務訪問代碼的方式也有利于測試。這樣在開發過程中,負責集成的程序員就可能在遠程服務還未完全實現的情況下,基于服務接口編寫集成代碼,并通過編寫POJO(Plain Old Java Object)構建偽服務實現來進行單元測試和模擬運行。這種開發方式對于保證分布式系統代碼質量具有重要意義。

    因此,為了解決上面的問題我們需要:

    1、將Web Service訪問的配置管理與代碼分離;

    2、解除客戶端代碼與遠程服務之間的依賴關系;

    3.2 利用IoC模式進行重構代碼

    我們先介紹在Core J2EE Patterns一書中提到的一種業務層模式:Business Delegate。它所要解決的問題是屏蔽遠程服務訪問的復雜性。它的主要思想就是將Business Delegate作為遠程服務的客戶端抽象,隱藏服務訪問細節。Business Delegate還可以封裝并改變服務調用過程,比如將遠程服務調用拋出的異常(例如RemoteException)轉換為應用級別的異常類型。

    其類圖如圖 2 所示:

    圖 2:Business Delegate 模式的類圖圖解

    Business Delegate模式實現很好地實現了客戶端與遠程訪問代碼的解耦,但它并不關注Delegate與遠程服務之間的解耦。為了更好解決Business Delegate和遠程服務之間的依賴關系,并更好地進行配置管理,我們可以用IoC模式來加以解決。

    IoC(Inversion of Contro)l意為控制反轉,其背后的概念常被表述為"好萊塢法則":"Don't call me, I'll call you." IoC將一部分責任從應用代碼交給framework(或者控制器)來做。通過IoC可以實現接口和具體實現的高度分離,降低對象之間的耦合程度。Spring是一個非常流行的IoC容器,它通過配置文件來定義對象的生命周期和依賴關系,并提供了良好的配置管理能力。

    現在我們來重構我們的Web Service應用程序,我們首先為Business Delegate定義一個接口類型,它提供了一個應用級組件接口,所有客戶端都應通過它來執行匯率計算,而不必關心實現細節,如清單 2 所示:

    清單 2:接口定義的代碼示例

    Public interface CurrencyExchangeManager {

    //貨幣兌換計算

    //新價格 = 匯率 * 價格

    public float calculate(String country1, String country2, float price)

    throws CurrencyExchangeException;

    }

    Business Delegate的實現非常簡單,主要工作是包裝匯率計算 Web Service的調用,如清單 3 所示。

    清單 3:Business Delegate的代碼示例

    public class CurrencyExchangeManagerImpl implements CurrencyExchangeManager {

    //服務實例

    private CurrencyExchangePortType stub;

    //獲取服務實例

    public CurrencyExchangePortType getStub() {

    return stub;

    }

    //設定服務實例

    public void setStub(CurrencyExchangePortType stub) {

    this.stub = stub;

    }

    //實現貨幣兌換

    public float calculate(String country1, String country2, float price)

    throws CurrencyExchangeException {

    try {

    //通過Stub調用WebService

    float rate = stub.getRate(country1, country2);

    return rate * price;

    } catch (RemoteException rex) {

    throw new CurrencyExchangeException(

    "Failed to get exchange rate!", rex);

    }

    }

    }


    共3頁: 1 [2] [3] 下一頁

    原文轉自:http://www.kjueaiud.com

    ...
    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>