摘要:在企業應用集成的發展進程中,組件扮演著十分重要的角色。組件類型的多樣性使得不同類型組件的集成工作面臨很大的困難,如何對不同的組件在合理規劃的基礎上進行統一管理,一直以來都是軟件設計師們研究的熱點。通過分析不同類型組件的特征,提出了將遠程組件本地化的思想,并基于此思想設計了服務訪問代理以及一個基于元數據的組件容器,在設計過程中運用了多種設計模式,以使其更加高效。
關鍵詞:企業應用集成;組件;本地化;組件容器;設計模式
中圖分類號:TP302文獻標識碼:A文章編號:1009-3044(2008)28-0105-02
Research on Component Integration Based on Service Access Proxy
BIAN Xiao-fan1, ZHAO Feng2
(1.Computer Center,Hebei University,Baoding 071002,China;2.College of Math and Computer,Hebei University,Baoding 071002,China)
Abstract: Component has played a key role during the process of Enterprise Application Integration (EAI). The diversity of components makes it a tough work to integrate components of different types, and software architects has been always focusing on the issue that how to mange different components in a uniform way based on an reasonable design. Through analyzing the component's attributes of different types, a thought of localizing the remote components was brought up, a service access proxy and a component container based on a metadata engine was designed on the basis of this thought, and lots of design patterns are applied to make it more effective.
Key words: EAI; component; localize; component container; design pattern
1 引言
在企業信息化的廣泛發展及不斷深化的過程中,企業應用集成技術發揮了重大作用。SOA(Service Oriented Architecture)的迅速發展及廣泛應用,促使了基于SOA的EAI的產生。在此大環境下,整個企業的所有系統都被視為一個個松散結構中的組件,系統接口、組件之間的通信、數據格式及轉換和組件目錄信息都應建立在開放、統一的標準之上,使得集成后的系統具有開放性、可擴充性等特點。
然而,在良好的分布式架構模式下,仍然存在一些性能和效率上的問題。在集成過程中,企業遺留系統往往被當作一個組件或服務發布,并通過RPC(遠程過程調用)的方式被應用系統調用或訪問。在一個大型的應用中可能要用到多種組件類型,有的以Web服務形式發布,也有的通過RMI、Hessian、HttpInvoker等技術發布。面對如此繁雜的組件類型,如果不提供一種合理的方式對它們進行統一管理,勢必會造成組件訪問方式的混亂,并最終影響系統的開發及運行效率。本文將從一個新的角度提出一種新的解決方案來優化組件的管理策略以及訪問性能。
2 設計思想
為了滿足快速搭建大型分布式應用的需要,除了編寫大量的本地組件以外,還要考慮將企業原有信息系統集成進來,從而極大的加速新系統的開發進程。然而我們又不得不面臨多類型組件混用帶來的設計上的復雜性。一個業務流程通常要借助多個組件的協作來完成,如果不對組件的獲取及調用進行統一管理,那么就不可避免的要在業務代碼中穿插很多組件訪問代碼,而且訪問方式各不相同,不但代碼可讀性差,而且給后期的維護埋下了巨大的隱患。
針對這一問題,有許多可供選擇的解決方案。一種普遍的做法是統一組件的發布方式,即將所有類型的組件以Web服務形式發布。這樣可以統一組件的獲取及調用方式,但是此方法的缺陷也是很明顯的。Web服務的通信是以SOAP為通信協議的,并以HTTP或SMPT為信息載體,對于絕大多數原本可直接訪問的本地組件,若都經過這樣一道程序,在訪問效率上自然就大打折扣。
綜合以上的分析,本文提出了在保持本地組件不變的基礎上,對遠程服務進行重構,并通過添加服務訪問代理的方式將其本地化,并通過一個基于元數據的組件容器對所有組件進行統一管理。該設計方案的總體架構如圖1所示。
圖1虛線框內為本架構的核心部分,主要由服務訪問代理和組件容器構成。其中,服務訪問代理負責對遠程的各種服務進行封裝,使其具有本地組件的特點。組件容器除了接收本地的組件,同樣也容納經服務訪問代理封裝后的代理組件,并對其管轄范圍內的組件的生命周期進行有效管理。另外,組件容器還要向應用程序提供統一的訪問接口,方便應用程序以唯一的方式調用組件。
3 詳細設計方案
3.1 遠程服務本地化思想
遠程服務本地化,即將遠程服務改裝成本地組件,使原先對遠程服務的操作變得如同訪問本地組件一樣簡便。為了達到這一目的,需要對遠程服務訪問代碼進行封裝,從而簡化遠程服務的獲取方式。這樣做最大的好處是屏蔽掉了各種遠程調用技術之間的差異,使不熟悉RPC方式的開發人員同樣可以參加到團隊合作中來,不但加快了開發進程,同時也縮減了培訓的開支。本文是以添加服務訪問代理的方式解決了遠程服務的本地化問題,并通過組件容器來最終實現遠程服務與本地組件的集成。
3.2 服務訪問代理
服務訪問代理主要完成兩個方面的工作。一方面是封裝遠程服務訪問代碼,另一方面是使其具有本地組件的一般形式,便于組件容器的識別以及統一管理。具體的做法我們參考了GoF的代理模式[2] ,對于每一個非本地組件,都在本地維護一個與其相對應訪問代理類。此代理類將與原組件擁有相同的方法或函數,只不過在方法體內的不是方法的具體實現,而是方法的調用代碼,從而完成遠程組件的本地化。實現過程可簡可繁,既可采取手工方式,也可以編寫一個工具來替你完成轉換工作,當然后者在前期工作量較大,但卻可以達到一勞永逸的效果。我們稱被代理后的遠程服務為代理組件,代理組件將與本地組件一同納入組件容器之中實行統一調度。
3.3 組件容器設計
組件容器的設置主要是對組件的生成、初始化、單例控制、銷毀等生命周期活動進行更有效的管理,并向應用程序提供統一的調用接口。在組件容器的設計過程中,我們利用元數據的平臺無關性[5],實現了組件的插件化管理,極大地減輕了后期維護的壓力,并保證了先期工作的效用最大化。組件容器的邏輯架構圖如圖2所示。
由圖2可知,組件容器大致由兩部分組成:元數據引擎和組件工廠,各部分功能詳述如下。
3.3.1元數據引擎部分
圖2中標注五角星的文件是組件配置文檔,它是該引擎的核心,其它一系列的輔助功能都是圍繞它展開的。各部分的功能及實現簡述如下:
1) 組件配置文檔應包含所供述組件的所有信息,并應具備可讀,和易解析的特點。XML作為W3C的一個標準,具有很強的通用性和很高的理論成熟度,并且有很多可供選擇的支持工具,所以理所應當地被選做本引擎的元數據載體。組件配置文檔的基本配置信息如下所示:
<component_list>
<cp id=\"cpProxy\" class=\"namespace.CpProxy\" singleton=\"true\">
<constructor>
<arg0 type=\"STRING\" value=\"arg0\"/>
<arg1 type=\"BYTE\" value=\"arg1\"/>
<!-- 其它參數 -->
<constructor/>
<setters>
<setter property=\"product\" type=\"STRING\">some_product</setter>
<setter property=\"amount\" type=\"INTEGER\">40</setter>
<!-- 其它setter -->
</setters>
</cp>
<!-- 其它組件配置 -->
</component_list>
配置信息的根元素為component_list,它代表了一個組件列表。cp則描述了一個具體的組件配置,id作為一個區別于其它組件的唯一性標志,而class則指明了該組件的代理類,后面的singleton可作為一個可選屬性,表征組件是否在系統運行過程中只保持有一個實例,參照了GoF的單例模式。constructor和setter分別代表組件類的構造函數和set方法,是為提供IOC支持而設置的。
IOC(Inversion of Control)控制反轉,又叫依賴注入[8],基本思想就是把對象的生命周期、依賴關系等交由容器來管理,而不是直接在應用中編程管理。通常IOC的實現有三種方式,本實例提供構造函數注入和設值注入兩種IOC方式供開發者選擇。
2) XML Schema又稱作XML Schema Definition(XSD),同樣是W3C的一個標準,它的作用是對XML的格式進行定義。在本引擎中它負責定義組件配置文檔的根元素、子元素以及元素的各種屬性,使其具備良好的格式。
3) 驗證器不是以元數據的形式呈現的,而是以編程的方式對配置文檔的合法性進行驗證,并對不合法的內容進行相應的出錯處理,其驗證規則正是由XML Schema定義的。
4) 組件解析器的設計相對比較復雜,在整個引擎的設計中編程工作量最大。解析器首先要讀取XML文檔中某個組件的配置,然后利用反射(Reflection)API將讀取到的組件信息解析成組件對象,并依據配置中的IOC相關的信息對組件對象進行初始化。由以上描述我們可以大概推斷出解析器的類結構,它內部應該維護了一個組件列表對象,同時還要提供特定的方法或函數來管理組件對象的生成,單例控制,初始化,銷毀。除此之外,它還必須向外界提供一個訪問組件的接口,實際上,這里所說的外界就是指圖2中的組件工廠。
3.3.2 組件工廠設計
組件工廠,即生產組件的場所,準確地說,它只負責獲取組件,因為在本系統中組件的生命周期是交由元數據引擎來管理的。應用系統獲取組件的唯一辦法就是通過組件工廠,而不與元數據引擎直接打交道。
有了前面的元數據引擎,組件工廠的設計就相對容易多了,一種最簡單的設計就是向組件的調用者暴露一個如getComponent(id)之類的方法,方法的實現也很容易,只需要調用元數據引擎中獲取組件的相應方法即可。這部分的設計參照了GoF的Factory設計模式。
4 性能優化策略及改進建議
1) 對于采用分布式架構的應用系統,由于大多數遠程組件的訪問都是通過HTTP協議完成的,所以可以考慮在客戶端、服務器,甚至在傳輸過程中所經過的連接器上適當施加HTTP自帶的緩存策略,可大大提高組件的訪問性能。
2) 在本系統中,組件的生成以及管理是與組件的獲取分離開的,這樣層次更加清晰。對于一些中小型的應用,出于執行效率考慮,可以把這兩部分合成一個單元,即把組件工廠也納入元數據引擎,與其中的解析器合并。
5 結束語
本文通過分析組件類型的多樣性以及EAI實施過程中的影響效率的關鍵問題所在,提出了一套新的組件集成方案,并設計了一個與此方案相配套的輕量級IOC容器。在一定程度上優化了組件訪問的性能和管理策略。
參考文獻:
[1] Masahiro Ohkawa.Provide a Facade interface for enterprise Web services [EB/OL].http://www.ibm.com/developerworks/library/ws-facade.
[2] Erich Gamma,Richard Helm,Ralph Johnson,et al.Design Patterns:Elements of Reusable Object-Oriented software[M].USA:Addison-Wesley,1995.
[3] Eric Freeman,Elisabeth Freeman,Kathy Sierra,et al.Head First Design Patterns[M].USA:O'Reilly Media,Inc,2007.
[4] 婁鋒,孫涌.輕量級IOC容器研究與設計[J].計算機技術與發展,2007,17(1):91-94.
[5] OMG.Technical Guide to Model Driven Architecture:The MDA Guide v1.0.1[EB/OL].http://www.omg.org/mda/presentations.htm.
[6] 楊中科.J2EE開發全程實錄[M].北京:清華大學出版社,2007:102-133.
[7] 黎建輝,吳威,閻保平.一種基于XML的元數據映像與轉換方法[J].微電子學與計算機,2008(1):40-44.
[8] Martin Fowler.Inversion of Control Containers and the Dependency Injection pattern[EB/OL].http://martinfowler.com/articles/injection.html.