使用Spring Framework設計和開發SCA組件,第1部分 - 三劍客:Spring、SCA和Apache Tuscany
在 “使用 Spring Framework 設計和開發 SCA 組件” 系列文章 中,學習如何有效結合服務組件架構(Service Component Architecture,SCA )與 Spring Framework 來創建分布式服務應用程序。第一篇文章將概述 SCA 與 Spring 兩者相結合的優勢。學習如何使用 Spring Framework 來設計和開發 SCA 組件,如何將 Spring beans 公開為 SCA 服務,以及如何在 Spring 應用 程序中訪問 SCA 服務和屬性。本文中的示例將使用 Apache Tuscany SCA Java™ 技術運行時。
簡介
在 Open SOA (OSOA) 項目發布標題為 “強大的組合:SCA 、OSGi 和 Spring” 的白皮書之後,這三種技術的結合引起了人們的一些 關注。Spring Dynamic Module 就是這種基礎架構的一種商業實現,它結合了 Spring 和 OGSi。Spring beans 可以作為服務組件架構(SCA)的組件實現使用 。Apache Tuscany 的Java 實現建立在 Apache 的OSGi 框架 (Felix) 的基礎之 上。
在本系列中,學習如何使用 Spring Framework 和 Apache Tuscany SCA Java 運行時來設計和開發 SCA 組件。示例和代碼片段將幫助您理解 SCA 與 Spring 兩者結合所帶來的好處。您還將了解如何結合 SCA 與 Spring 來創 建分布式服務應用程序。
本文將介紹使用 Spring 開發 SCA 組件時需要 掌握的一些基本設計原則。您將探索如何將 Spring beans 公開為 SCA 服務, 以及如何在 Spring 應用程序中訪問 SCA 服務和屬性。
第 2 部分將深 入討論一些高級特性,比如說通過 SCA 處理多種應用程序上下文以及在 Spring beans 中使用 SCA 注釋。
下載 示例源代碼。此示例需要在 Apache Tuscany 運行時中運行,但其側重 點並不是展示如何開發 SCA 組件。本文將重點討論如何將 Spring 應用程序作 為 SCA 組件的一種實現技術來使用。
程序
本文將討論以下程序。
SCA提供了一個編程模型,用於創建基於面向服務架構(Service-Oriented Architecture ,SOA)的應用程序和解決方案。SCA 所依托的理念是將業務功能 作為一系列服務提供,從而創建能滿足特定業務需求的解決方案。這些復合集可 以包含為已有系統中的應用程序和業務功能創建的新服務,以及作為復合應用的 一部分重用的應用程序。SCA 提供了:
一個用於服務復合以及服務組件創建的模型,包括在 SCA 復合集中重用已有 應用程序。
靈活的復合、重用、技術和部署選擇,這使它成為了構建異構分布式系統的 理想環境。
支持多種實現語言和通信機制。
簡化的組件編程模型,用於使用各種技術(比如說 Enterprise JavaBeans、 Java POJOs、Spring beans、BPEL Process、COBOL、C++ 和 PHP 等)來實現業 務服務。
Spring Framework通常稱作 Spring,它是一個嘗試通過解決企業應用程序開 發的復雜性來提高 J2EE 環境適用性的開源項目。Spring 的一個優勢在於它的 分層架構。它允許您選擇所使用的組件,同時為 J2EE 應用程序開發提供了一個 緊密結合的框架。Spring 為簡單的Java 對象提供了一個框架,從而使它們能夠 通過包裝器類和 XML 配置來使用 J2EE 容器。Spring 的目標是,通過提高開發 生產力和運行時性能,讓項目從中獲得巨大的好處,並改善測試范圍和應用程序 質量。人們經常將 Spring 描述為一種輕量級的容器環境,但更加恰當的比喻或 許是 “能簡化開發的框架“。Apache Tuscany開源 Apache Tuscany 項目致力 於實現 SCA 規范(和一些其他的SCA 規范,如 Service Data Objects 和 Data Access Service)。依照 Open Service-Oriented Architecture (OSOA) 和針 對全球信息社會 (OASIS SCA Java) 規范的一些標准,Apache Tuscany 為 SCA 運行時提供了一個全面的基礎架構。本文中的示例將使用 Apache Tuscany V1.5 ,它是截止本文撰寫時的最新版本。要運行示例應用程序,需要 下載 Apache Tuscany SCA Java 實現的二進制發行版。
SCA Assembly Model
SCA 的基本工件是組件,它是 SCA 的基本構成單元。組件包含一個經過配置 的實現實例,其中,實現是提供業務功能的程序代碼。業務功能將由其他組件作 為服務提供。實現有時需要依賴於其他組件提供的服務。這些依賴關系被稱作 引用。
實現具有可設置的屬性,它們是影響業務功能運轉的數據值。組件通過為屬 性提供值以及將引用關聯到其他組件所提供的服務來配置實現。多個組件可以使 用和配置同一實現,而每個組件可以采用不同的方式來配置實現。
SCA 支持:
各種實現技術,比如說 Java POJOs、EJBs、Spring beans、BPEL Process、 COBOL 和 C++
一些腳本語言,比如說 PHP 和 JavaScript
一些聲明式語言,比如說 XQuery 和 SQL
SCA 在一種被稱作復合集(composites) 的集合中描述應用程序的內容和關 聯,如圖 1 所示。復合集可以包含組件、服務、引用、屬性聲明以及這些元素 之間的關聯描述。復合集可以分組和鏈接采用不同實現技術構建的組件,從而允 許在各業務任務中采用適當的技術。復合集將部署在 SCA 域中。
圖 1. SCA 復合圖
SCA Assembly Model 包含一系列工件,它們在復合集方面定義了 SCA 域的 配置,其中包括服務組件以及描述組件之間的關聯的相關工件。
SCA 與 Spring 兩者相結合的優勢
Spring Framework 與 SCA 采用許多相同的設計原則。SCA 將 Spring 視為 其組件的一種實現技術。SCA Spring Component Implementation Specification 定義了如何采用這種方式來使用 Spring。
與 Spring bean 類似,SCA 組件可以包含到其他組件所提供的服務的引用, 並且有一些屬性可供配置。與 Spring 形成對比的是,SCA 是一種跨語言的分布 式組件架構,它支持多種組件通信機制。通過將 Spring beans 發布為可由其他 組件訪問的服務並為 Spring beans 提供關聯到其他(可能為遠程)組件的服務 的引用,SCA 可以擴展 Spring 組件的功能。
要將 SCA 與 Spring 相結合,一種有效的方法是使用 Spring 來構建 “粗 粒度” 的服務組件實現,並引入到 SCA 中以便公開服務、關聯服務組件以及處 理異構和分布式系統。SCA 可以在使用 Spring 實現的應用程序中添加一些有用 的功能,比如說:
對遠程組件以及多種協議的擴展支持
支持使用不受 JVM 支持的各種編程語言來編寫組件
支持 WS-Policy 針對安全性和事務等活動指定的策略
易於測試組件是 Spring 的一項優異的特性。缺少 API 和注入技術導致您只 能使用簡單的模擬對象進行測試。SCA 在服務方面對此進行了補充,因為關於服 務組件的SCA 復合集可以方便地切換到模擬配置以進行測試。
將 Spring 應用程序定義為 SCA 組件
在 Apache Tuscany SCA 實現中,SCA 使用 Spring 作為其組件在 SCA 復合 集中的實現技術。可以將 Spring 應用程序定義為 SCA 復合集中的SCA 組件, 即 SCDL,其格式如下所示。
清單 1. 包含一個 Spring 組件的SCA 復合集
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
targetNamespace="http://calc"
xmlns:c="http://calc"
name="Calculator">
<component name="CalculatorServiceComponent">
<implementation.spring location="targetURI"/>
</component>
</composite>
<implementation.spring> 元素的位置屬性可以指定目標 URI 指向某 個存檔文件 (.jar) 或 目標,或者 直接指向 Spring 應用程序上下文。
以下列表給出了指定 <implementation.spring> 位置屬性的目標 URI 的可能方法。
指定 Spring 應用程序上下文文件
<implementation.spring location="application-context.xml"/>
指定目錄
<implementation.spring location="./spring"/>
目標 URI 將資源指定為名稱為 spring 的目錄,其中包含所有與 Spring 相 關的文件。META-INF/MANIFEST.MF 文件必須包含在 Spring 目錄中,它使用 Spring-Context ::= <path> 格式的Spring-Context 頭部指定到上下文 配置的路徑。其中,path 相對於 Spring 目錄。如果 MANIFEST 文件中沒有 MANIFEST.MF 文件或 Spring-Context 頭部,則默認行為是使用 Spring 目錄下 的META-INF/spring 目錄中的application-context.xml 文件建立應用程序上下 文。 指定存檔文件
<implementation.spring location="spring.jar"/>
目標 URI 將資源指定為 spring.jar 存檔文件,其中包含與 Spring 相關的 所有文件。META-INF/MANIFEST.MF 文件必須位於 spring.jar 存檔文件中,它 使用 Spring-Context ::= <path>. 格式的Spring-Context 頭部指定到 上下文配置文件的路徑。其中,path 指向 spring.jar 存檔中的文件。如果 MANIFEST 文件中沒有 MANIFEST.MF 文件或 Spring-Context 頭部,則默認行為 是使用目錄 spring.jar 存檔文件中 META-INF/spring 目錄下的application- context.xml 文件建立應用程序上下文。
基於 Spring 的SCA 組件
組件實現的業務功能將由其他組件作為服務 提供。實現可以依賴其他組件提 供的服務;這些依賴關系被稱作引用。實現可以有可設置的屬性,即影響業務功 能運轉的數據值。下面的例子展示了如何將 Spring beans 提供為 SCA 服務, 以及如何在您的Spring 應用程序上下文中配置 SCA 引用和 SCA 屬性。
示例
我們以圖 2 中的CalculatorComponent 為例。它需要依賴其他組件 (AddComponent、SubtractComponent、MultiplyComponent 和 DivideComponent)來實現所需的功能。在本例中,CalculatorComponent 的業 務功能是使用 Spring beans 實現的,AddComponent 是使用 JavaScript 實現 的,SubtractComponent 和 MultiplyComponent 是使用簡單 POJO 實現的,而 DivideComponent 是使用 Groovy 腳本實現的。
圖 2. 基於 Spring 的CalculatorComponent
下一步是創建一個名稱為 calculator.composite 的SCA 復合集(如清單 2 所示)來定義組件、服務、引用、屬性聲明以及這些元素之間的關聯描述。詳細 信息請參見 下載 小節。
清單 2. calculator.composite
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
targetNamespace="http://calc"
xmlns:c="http://calc"
name="Calculator">
<component name="CalculatorComponent">
<implementation.spring location="META-INF/spring/calculator- context.xml"/>
<service name="CalculatorService">
<interface.java interface="calculator.CalculatorService"/>
<t:binding.rmi host="localhost" port="8099"
serviceName="CalculatorRMIService"/>
</service>
<reference name="addService" target="AddComponent" />
<reference name="subtractService" target="SubtractComponent" />
<reference name="multiplyService" target="MultiplyComponent"/>
<reference name="divideService" target="DivideComponent" />
</component>
<component name="AddComponent">
<t:implementation.script script="calculator/AddServiceImpl.js"/>
</component>
<component name="SubtractComponent">
<implementation.java class="calculator.SubtractServiceImpl"/>
</component>
<component name="MultiplyComponent">
<implementation.java class="calculator.MultiplyServiceImpl"/>
</component>
<component name="DivideComponent">
<t:implementation.script script="calculator/DivideServiceImpl.groovy"/>
</component>
</composite>
calculator.composite 使用 <reference> 元素定義 CalculatorComponent 與其他四個服務之間的依賴關系,比如說 AddComponent 、SubtractComponent、MultiplyComponent 和 DivideComponent。它們是使用 不同技術實現的。AddComponent 提供 addService 實現,用於返回兩數之和。 同樣,SubtractComponent 提供 subtractService 實現,用於返回兩數之差。 MultiplyComponent 提供 multiplyService 實現,用於返回兩數之積。 DivideComponent 則提供 divideService 實現。
您可能注意到在 calculator.composite 中,AddComponent、 SubtractComponent、MultiplyComponent 和 DivideComponent 並未使用 <service> 元素明確公開任何服務(采用這種方式,本示例聲明為 CalculatorComponent 公開了 CalculatorService)。這樣,當您的SCA 組件未 使用 <service> 元素明確公開任何服務時,則 SCA 運行時默認會使用 binding.sca 綁定公開您的組件。同樣,在 CalculatorComponent 中,您不必 為這些組件引用指定任何具體的綁定信息。SCA 運行時提供了默認的 binding.sca 綁定,用於關聯各組件。有關 binding.sca 的詳細信息,請參閱 SCA Assembly Model Specification。
在本例中,CalculatorComponent 是一個 Spring 應用程序,它使用 Spring beans 定義了業務邏輯。在您的Spring 應用程序上下文定義文件中聲明所需的 SCA 依賴關系非常重要。
創建一個名稱為 calculator-context.xml 的Spring 應用程序上下文定義文 件。如清單 3 所示,通過聲明實現所需功能需要的beans 以及它們的依賴關系 ,提供了 CalculatorComponent 的業務邏輯。
清單 3. calculator-context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance"
xmlns:sca="http://www.springframework.org/schema/sca"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring- beans.xsd
http://www.springframework.org/schema/sca
http://www.osoa.org/xmlns/sca/1.0/spring- sca.xsd">
<bean id="Calculator" class="calculator.CalculatorServiceImpl">
<property name="add" ref="addService"/>
<property name="subtract" ref="subtractService"/>
<property name="multiply" ref="multiplyService"/>
<property name="divide" ref="divideService"/>
</bean>
</beans>
在 calculator-context.xml 中,calculator bean 通過將所需的依賴關系 設置為屬性定義了 CalculatorComponent 的業務邏輯。對於 Spring bean 來說 ,每個屬性都是對要設置的值的實際定義,或容器中另一個 bean 的引用。在本 例中,calculator bean 依賴於復合集中的組件所提供的各種 SCA 服務,因此 應該將屬性設置為引用(設置 ref 屬性的值)calculator.composite 中定義的 SCA 引用。由於目標是將 CalculatorComponent 公開為服務,因此還應聲明需 要為 calculator.composite 中定義的SCA 服務公開哪些 bean。
Spring 組件實現規范和 Apache Tuscany SCA 運行時允許您將 SCA 引用和 屬性聲明為 bean 屬性。您還可以聲明被顯式或隱式地公開為 SCA 服務的bean ,如下所述。
聲明顯式 SCA 服務、引用和屬性
SCA Spring Component Implementation Specification 和 Apache Tuscany SCA 運行時允許您使用 Spring SCA 模式中的自定義 SCA 名稱空間元素在 Spring 應用程序上下文文件中聲明 SCA 服務、引用和屬性。您可以使用自定義 SCA 名稱空間元素將 Spring beans 聲明為 SCA 服務,並通過 SCA 組件定義指 定到所獲取的SCA 服務和屬性的引用。使用 Spring 應用程序上下文文件中的 SCA 名稱空間元素被稱作 SCA 服務、引用和屬性的顯式聲明。
用於在應用程序上下文文件中聲明 SCA 服務、引用和屬性的自定義 SCA 名 稱空間將在下面詳細討論。
<sca:service> 允許您控制需要將哪些 Spring bean 公開為 SCA 服 務。為您提供一種方式來控制將哪些 Spring bean 公開為 SCA 服務。SCA 運行 時負責創建合適的服務器綁定,根據 SCDL 配置將需要的策略應用到這些服務上 。<sca:reference> 為您提供一種方式來聲明 Spring 應用程序上下文對 復合集中的其他 SCA 組件所提供的服務的依賴關系。該 SCA 運行時負責創建合 適的引用綁定,根據 SCDL 配置將需要的策略應用到這些服務上。 <sca:property> 為您提供一種方式來聲明 Spring 應用程序上下文對由 SCA 組件實現提供的可設置屬性的依賴關系。<sca:property> 元素的 name 屬性應該在復合集中擁有一個與所含組件相匹配的SCA 屬性。
在 calculator-context.xml(在 清單 3)中使用自定義名稱空間元素聲明 SCA 服務、引用和屬性,如下所示。
清單 4. calculator-context.xml
<beans xmlns="http://www.springf
ramework.org/schema/beans"
xmlns:xsi="http://www.w3.org
/2001/XMLSchema-instance"
xmlns:sca="http://www.springframework.org/schema/sca"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring- beans.xsd
http://www.springframework.org/schema/sca
http://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd"
> <sca:service
name="CalculatorService" type="calculator.CalculatorService" target="Calculator"/>
<bean id="Calculator" class="calculator.
CalculatorServiceImpl">
<property name=
"add" ref="addService"/>
<property name=
"subtract" ref="subtractService"/>
<property name=
"multiply" ref="multiplyService"/>
<property name=
"divide" ref=
"divideService"/>
</bean>
<sca:reference name=
"addService" type=
"calculator.AddService"/>
<sca:reference name=
"subtractService" type="calculator.SubtractService"/>
<sca:reference name=
"multiplyService" type="calculator.MultiplyService"/>
<sca:reference name=
"divideService" type=
"calculator.DivideService"/>
</beans>
如清單 4 所示,<sca:service> 元素聲明提供 CalculatorService 作為來自目標 calculator bean 的SCA 服務。必需的name 屬性擁有的值應該與 在 calculator.composite 中為 CalculatorComponent 定義的<service> 元素的名稱相同。必需的type 屬性應該將服務類型聲明為一個 Java 類的完全 限定名。必需的target 屬性應該擁有應用程序上下文中的一個 <bean/> 元素的名稱,該元素提供由此 <sca:service> 元素聲明的服務。
清單 4 中的<sca:reference> 元素聲明此應用程序上下文對由復合集 中其他可用的SCA 組件提供的服務的依賴關系。在本示例中,calculator bean 依賴於 SCA 服務,比如 AddComponent、SubtractComponent、 MultiplyComponent 和 DivideComponent。這些依賴關系使用 <sca:reference> 元素進行聲明。此元素的必需 name 屬性擁有的值應該 與在 calculator.composite 中為 CalculatorComponent 定義的 <reference> 元素的名稱相同。必需的type 屬性應該將服務的類型聲明 為一個 Java 類的完全限定名。對於 calculator.composite 的 CalculatorComponent 中的每個 <reference> 元素,會在 Spring 應用 程序上下文中聲明一個等效的<sca:reference> 元素。
類似地,<sca:property> 元素允許您聲明此應用程序上下文對 calculator.composite 中的CalculatorComponent 提供的SCA 屬性的依賴關系 。必需的name 屬性擁有的值應該與 calculator.composite 中為 CalculatorComponent 定義的<property/> 元素名稱相同(如 清單 2 中 所示)。必需的type 屬性應該將屬性類型聲明為一個 Java 類的完全限定名。
聲明隱式的SCA 服務、引用和屬性
SCA Spring Component Implementation Specification 和 Apache Tuscany SCA 運行時支持直接在 Spring 應用程序上下文文件中聲明 SCA 服務、引用和 屬性,無需使用在 Spring SCA 模式中定義的任何自定義 SCA 名稱空間元素。 在 Spring 應用程序上下文文件中直接使用 SCA 引用和屬性(無需自定義 SCA 名稱空間)稱為 SCA 服務、引用和屬性的隱式聲明。清單 3 中的calculator- context.xml 是一個例子。
在 calculator.composite 文件中定義的具有 addService、 subtractService、multiplyService 和 divideService 等名稱的SCA 引用(參 見 清單 2)可以直接用作 Spring 應用程序上下文中的bean 引用(如 清單 3 所示)。calculator bean 屬性可以設置為使用 SCA 引用名直接引用(設置 ref 屬性的值)在 calculator.composite 中定義的SCA 引用(清單 2)。在這 種情況下,bean 引用的類型將由 Tuscany 運行時從 bean 類定義中進行內省( introspect),以驗證它並將它與在復合集中定義的SCA 應用類型相匹配。
類似地,在 SCA 復合集中定義的SCA 屬性可以直接用作 Spring 應用程序上 下文中的bean 引用。將 bean 屬性設置(設置 ref 屬性的值)為使用 SCA 屬 性名稱引用在 calculator.composite 中定義的SCA 屬性。
當應用程序上下文中沒有顯式的<sca:service> 元素時,所有頂級的 bean 都將被公開為 SCA 服務,使用 bean 名稱作為服務名稱。任何內部 bean 或抽象 bean 都不會被用於隱式服務創建。當 Spring bean 實現類實現多個接 口時,這些 bean 可以被公開為單個或多個服務。您使用顯式的 <sca:service> 元素,其中每個 <sca:service> 元素引用相同的 <bean> 元素,但 type 屬性僅使用由 bean 提供的接口之一。在隱式創 建服務時,bean 被公開為單一服務,方法是將 bean 類本身聲明為服務的一個 接口。
盡管 Apache Tuscany SCA 運行時支持使用隱式 SCA 服務、引用和屬性,但 也有一些場景不適合使用隱式聲明。
場景 1. 為集合使用隱式 SCA 引用和屬性
在 Spring 中,<list/>、<set/>、<map/> 和 <props/> 元素允許分別定義和設置 Java Collection 類型 List、Set、 Map 和 Properties 的屬性和參數。清單 5 中的示例 bean 定義演示了在 Spring 的<list/>、<set/> 和 <map/> 元素中使用隱式 SCA 引用和屬性的局限性。
清單 5. 集合的隱式 SCA 引用
<bean id="moreComplexObject" class="example.ComplexObject">
<!-- results in a setSomeList(java.util.List) call -->
<property name="someList">
<list>
<value>a list element followed by a reference</value>
<ref bean="mySCAReference1" />
</list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property name="someMap">
<map>
<entry>
<key>
<value>an entry</value>
</key>
<value>just some string</value>
</entry>
<entry>
<key>
<value>a ref</value>
</key>
<ref bean="mySCAReference2" />
</entry>
</map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property name="someSet">
<set>
<value>just some string</value>
<ref bean="mySCAReference3" />
</set>
</property>
</bean>
假設名為 someList 的bean 屬性的bean 實現被定義為清單 6 的內容。List 被聲明為泛型,以接收其集合中任何類型的Java 類。
清單 6. someList 屬性的bean 實現
private
List<?> someList;
public List<?> getSomeList() {
return someList;
}
public
void setSomeList(List<?> someList) {
this.someList = someList;
}
在此場景中,Apache Tuscany 運行時無法內省此集合所需的SCA 引用對象的 准確類型(類型 mySCAReference1、mySCAReference2 和 mySCAReference3)。 必需的SCA 引用注入將失敗。當 someMap 和 someSet 屬性被聲明為接受其集合 中任何類型的Java 類時,相同的規則也適用於它們。建議您總是顯式地使用 <sca:reference> 元素聲明 SCA 引用,並在這類場景中使用必需的name 和 type 屬性。
場景 2. 為構造函數注入使用隱式 SCA 引用和屬性
Spring 中的構造函數注入允許您通過類構造函數注入依賴關系。為了減少潛 在的歧義,Spring 建議只要在 bean 實現中定義了多個構造函數,就為 <constructor-arg> 元素適當使用 index 和 type 屬性。
Tuscany 還建議為 <constructor-arg> 元素使用 index 和 type 屬 性,為所有構造函數注入場景顯式聲明相關的SCA 引用,即使 bean 只有一個構 造函數。
例如,假設您想要使用構造函數為 calculator bean 注入必需的依賴關系( 必需的SCA 引用)。您應該像清單 7 所示的那樣定義 bean。在 Tuscany 中, 不支持為構造函數使用隱式 SCA 引用和屬性。
清單 7. 針對 calculator bean 的構造函數注入
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema- instance"
xmlns:sca="http://www.springframework.org/schema/sca"
xsi:schemaLocation="
http://www.springframework.
org/schema/beans
http://www.springframework.
org/schema/beans/spring-beans.xsd
http://www.springframework.
org/schema/sca
http://www.osoa.org/xmlns
/sca/1.0/spring-sca.xsd">
<bean id="Calculator" class="calculator.CalculatorServiceImpl">
<constructor-arg index="0" type="calculator.AddService" ref="addService"/>
<constructor-arg index="1" type="alculator.SubtractService"
ref="subtractService"/>
<constructor-arg index="2" type="calculator.MultiplyService"
ref="multiplyService"/>
<constructor-arg index="3" type="calculator.DivideService" ref="divideService"/>
</bean>
<sca:reference name="addService" type="calculator.AddService"/>
<sca:reference name="subtractService" type="calculator.SubtractService"/>
<sca:reference name="multiplyService" type="calculator.MultiplyService"/>
<sca:reference name="divideService" type="calculator.DivideService"/>
</beans>
SCA 運行時中的應用程序上下文創建
在 Spring 中,主要的模塊單元是應用程序上下文,它包含一定數量的bean (由 Spring 應用程序上下文管理的對象)。應用程序上下文可以在一個分層結 構中配置,在其中,子應用程序上下文可以看到父應用程序上下文中定義的bean ,但反之則不行。
默認情況下,Spring 容器在創建容器時驗證每個 bean 的配置,包括驗證 bean 引用是否實際引用了有效的bean。對於包含對 SCA 引用和屬性的引用的 Spring 應用程序上下文,為在 Spring 應用程序上下文中使用的所有 SCA 引用 和屬性創建有效 bean 是 SCA 運行時的職責。然後,Spring 容器可以驗證 bean 並成功加載應用程序上下文。圖 3 給出了一個示例。
圖 3. 具有父上下文的SCA 運行時
Tuscany 運行時使用 Spring Binary V2.5.5 加載和運行目標應用程序上下 文,這些上下文在 <implementation.spring> 元素的location 屬性中指 定,而該元素在 calculator.composite 文件中定義(如 清單 2 所示)。在加 載目標應用程序上下文之前,Tuscany 運行時嘗試:
內省目標應用程序上下文定義文件,確定在 Spring 應用程序上下文中聲明 的SCA 服務、引用和屬性。
使用合適的Spring bean,為在目標應用程序上下文中聲明的所有 SCA 引用 屬性創建一個 SCAParentApplicationContext。
在上面的示例中,使用合適的Spring bean 為在 calculator-context.xml 文件中聲明的所有 SCA 引用(比如 addService、subtractService、 multiplyService 和 divideService)創建了一個 SCAParentApplicationContext(參見 圖 3)。隨後,使用 org.springframework.context.support.GenericApplicationContext 創建目標 應用程序上下文,將 SCAParentApplicationContext 聲明為它的父上下文。
Tuscany 運行時還提供了必要的基礎設施來創建合適的服務綁定,根據 SCDL 配置,為使用 Spring bean 實現的這些服務提供必需的策略。
結束語
本文介紹了如何使用基於 Spring 的應用程序設計和開發 SCA 組件。您現在 可以使用自定義 SCA 名稱空間元素,在 Spring 應用程序上下文中顯式聲明 SCA 服務、引用和屬性,可以在 Spring 應用程序上下文中直接聲明 SCA 引用 和屬性。您了解了 SCA 運行時如何為 SCA 組件創建目標應用程序上下文。借助 示例,本文簡短介紹了在應用程序上下文中使用隱式 SCA 引用和屬性的局限性 。
SCA 和 Spring 能夠構成一個強大的組合。Spring 提供了基礎設施來開發具 有更高效率和運行時性能的組件,還改進了測試覆蓋率和應用程序質量。SCA 提 供了必要的基礎設施來組裝和建模基於 SOA 的組件,支持組件公開服務,將服 務組件連接在一起,以及處理異構的分布式系統。
敬請期待第 2 部分的推出,第 2 部分將介紹一些高級特性,比如使用 SCA 處理多種應用程序上下文,在 Spring bean 中使用 SCA 注釋。
本文配套源碼