作者:  Anders小明


什么是企業應用下的業務組件

首先,這是一個組件,這意味著它需要在容器里運行,因此不包括任何中間件服務,同時以一定結構(文件結構或者壓縮格式)組成,被容器識別;其次,這是一個業務組件,即提供的是應用服務,而非技術服務;第三,這是企業應用,在業務上包括功能和服務(Service,當前最時髦的說法,你可以理解為API),技術上(以J2EE來講)包括:UI資源(JSFJSPJSCSS等)、應用程序(Java)資源和配置文件、數據庫表定義、初始化數據和存儲過程。

為什么要企業應用下的業務組件

組件技術從提出到現在已經有20多年了,為什么要提企業應用業務組件?因為現有的組件技術不支持企業應用環境下的組件要求,J2EEEJB不支持,.NETDLL也不支持。

如前所述,一個企業應用通常包括了交互界面、應用代碼以及數據庫結構,而不論是EJB還是DLL只支持應用代碼,都不包括交互界面和數據庫結構。

如果說EJB不是,那么J2EEEAR或者WAR是否算是一個組件?答案也不是,EAR或者WAR部署的是一個企業應用,請注意EJB規范中明確說:The Enterprise JavaBeans architecture is a architecture for the development and deployment of component-based (distributed) business applications(EJB 2.x3.x唯一的區別是2.xdistributed),它們有自己的應用域,彼此相互隔離(簡單的看,它們有各自獨立的會話管理)。.NET也是有自己的應用域概念。

更進一步,基于應用的部署導致了三個隔離問題:交互(界面)隔離程序訪問隔離數據隔離(請注意這三個問題分別對應了企業應用業務組件的三個技術內容)。交互隔離導致了企業用戶必須訪問不同界面,代碼訪問隔離導致了點對點的集成以及諸如性能、事務和異步處理等各種非功能性問題,而數據隔離導致了數據有效性、一致性等等問題。所有這些都進而導致了維護的問題。

為了解決這些問題,大廠商們都提出了各種解決方案:Portal來解決交互隔離問題,通過ESB來解決代碼訪問隔離問題,以及通過所謂的信息服務(Information Service)來解決數據隔離問題。

那么OSGi技術或者SCA技術能否滿足要求?答案是目前不能,OSGi最初開發的目的就不是為了企業應用,只是這幾年開始成熟,并向企業應用方向發展。09年推出的企業版(草案)剛剛提出針對程序訪問問題的方案,如遠程服務、事務管理等;交互隔離問題上規范并沒有提出相應方案,只有EclipseEquinox提出了界面的擴展點機制,但這也不能解決B/S環境的問題;而數據隔離問題就沒有任何方案。SCA從一開始就是面向企業應用,不過不解決交互隔離和數據隔離問題。

此外,對于行業ISV來說,除企業用戶面臨的這些種種問題,還面臨著其它問題。企業用戶畢竟只是面對自己的需求,行業ISV卻面臨著多個企業用戶的需求,面臨定制化帶來的維護問題,特別是業務和技術的隔離問題(即如何保持構建業務組件的所使用技術的平穩升級)。

組件的容器

既然要企業應用下的業務組件,而現有的組件技術又無法支撐,那么就需要一個新的組件容器了(當然,作為一個普通開發人員,我們無法新建一個公開標準的組件體系,也獨立維護一個私有的)。新的組件容器完全使用現有的中間件技術,并加上一些新的內容,包括如下:

  1. 組件框架,識別組件,以及組件(文件)結構和各個技術工件。
  2. 技術框架,提供業務無關的技術支持,以便于技術的平穩升級切換。
  3. 運行容器,采用現有中間件技術,包括Tomcat、應用服務器和數據庫服務等;
  4. 工具,包括打包以及部署工具等。

關于數據隔離問題,在EIP中提到了各種解決方案,這里采用的共享數據庫方式,即各個組件都共用一個數據庫,各個組件只提供數據庫定義和初時數據(如同EJB/OSGi一樣,運行時環境由容器提供)。

組件的關系

組件的關系分為兩種:依賴和聯動。依賴關系在已有的組件技術上已經廣為認知,而聯動則是新創造的(肯定不是第一個創建的,只不過不同人有不同的叫法)。

聯動和依賴的區別是:如果有組件B和組件A聯動,則組件B可以在沒有組件A的情況下運行,并提供相應功能。

針對三種不同技術工件(即三個隔離問題)呈現不同特點,如下:

1. UI資源(交互隔離問題),依賴是指UI資源的嵌入、引用和替換,聯動是指UI資源的新增。

2. 應用程序(程序訪問隔離),依賴是指API/模型依賴,聯動是指消息(傳統消息和JMS消息)以及SPI實現。其中,無論是依賴或者聯動都涉及到相應的非功能性需求,包括:異步、事務控制和服務時限等。

3. 數據庫資源(數據隔離),依賴是指外鍵關聯和級聯操作,無明顯的聯動關系。

這里,需要關注應用程序的依賴和聯動

1. SPIAPI存在業務不匹配問題。

雖然組件A依賴組件B,但是不代表組件B提供的服務完全匹配組件A的要求。有時組件A所需要的數據需要組件B的多個API組成,為了開發方便或者組件A所需要的性能問題,可能會在組件B新寫一個接口給組件A使用,注意該接口不是組件BAPI,該接口僅適用于組件A

2. 盡可能的使用SPI集成方式

SPI集成方式是相對于API集成方式,API集成方式就是,組件B直接調用其它組件的API及其模型。SPI集成方式(類似于依賴倒置),組件B定義其所需要的接口及其模型,由組件A或者膠水層代碼來實現。

這個點對于行業ISV尤為明顯。對于企業用戶來說,依賴是明確的,組件A依賴/聯動于組件B,但對于行業ISV,則面臨著定制化問題,雖然組件A依賴/聯動于組件B,但是在某個定制化項目中,由于客戶已有系統C,而需要組件A依賴/聯動于客戶已有系統C。此時采用SPI方式。

在開源世界里采用SPI方式更是廣泛。很多框架為了兼容(同一功能)不同實現的類庫,都是先定義框架所需接口,并同時提供不同類庫的膠水代碼。

不論是EJB/OSGi/SCA都沒有對SPI集成方式的支持。

3. 依賴和聯動的非功能性需求。

事實上,非功能性需求都是在集成時才存在的。以事務管理為例,除了及其少數的例子外,大部分事務只能在處理流程才被決定(注意,EJB在這方面著是定義在API上的,這樣的設計是不適應需求的),而組件AAPI在用例1中需要被異步調用,而在用例2中需要被同步調用是常見的。即便是OSGi規范,也在這方面沒有任何處理。

組件的定制化

定制化問題只針對于行業ISV有效,對于企業用戶來說,除非是那種跨國企業在面臨不同國度的業務模式、法律監管和會計制度等差異,存在定制化需要,即使如此,ISV和企業用戶對于同一問題的解決方式也是不同的。

既然我們已經將原有的應用采用組件化方式開發,那么應用的定制化問題就轉化為組件的定制化問題。同樣,應用的定制化手段也就轉化為組件的定制化手段。

組件框架

       羅羅嗦嗦的說了半天,有人就說了:這不就是把UIJava和數據庫三個東東一打包,然后說這就是一個企業應用下的業務組件,有啥新意呢,不就是模塊化開發嘛,一直一來大家都是就是這么搞的嘛,何必搞個怪名詞來忽悠。

       是的,就是把UIJava和數據庫三個東東整合在一起,組件容器說提到的技術框架很多的開發隊伍都有一套,運行容器更是有無數開源商業的,打包部署工具更是寫了無數。

這確確實實就是我們常說的模塊化開發。但是模塊化開發不同于組件開發,模塊化開發只是在邏輯上做了切分,物理上(開發出的系統代碼)通常并沒有真正意義上的隔離,一切都只是在文檔中。

我們需要一點干貨,只有實實在在的組件框架才能組件化開發真正落地的(如同OSGi框架那樣):我們需要一個類似于Equinox的界面擴展框架來支持UI資源的依賴和聯動;我們需要一個集成框架來支持應用程序的依賴和聯動,解決所面臨的種種問題(業務不匹配、SPI集成以及各種非功能性需求);我們需要一個打包部署工具(類似Spring DM)提供部署UI資源、應用程序和數據庫定義資源(Spring DM提供了基于Web資源的部署能力)。

其它問題

對于采用J2EEB/S環境的組件應用還面臨一個問題,即現有Servlet規范只允許一個web.xml,不支持組件各自定義私有的FilterServlet,不過這個問題不是很嚴重,在現有技術框架已經支持一份簡單的web.xml,而新的Servlet規范已經允許多個web.xml

分布式部署以及集群部署問題,這其實不是個問題。基于應用的我們有很多手段和技術,那么基于組件的也一樣有辦法。