首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring Framework 與 SCA 整合開發指南(一):三劍客——Spring、SCA 與 Apache Tuscany

     編輯:Java 相關知識

前言

在開放 SOA (OSOA) 專案發布《強大的組合:SCA、OSGi 與 Spring》白皮書後,這三大技術的結合引起廣泛關注。Spring Dynamic Modules 是結合 Spring 與 OSGi 的商業實現之一,而 Spring beans 可作為服務組件架構(SCA)的組件實現。Apache Tuscany 的 Java 實現建立在 Apache Felix (OSGi 框架) 之上,為 SCA 運行時提供完整基礎設施。

系列文章概覽

本系列將示範如何結合 Spring Framework 與 Apache Tuscany SCA Java 運行時,設計與開發 SCA 組件。透過範例與代碼片段,您將理解 SCA 與 Spring 結合的優勢,並學會建立分散式服務應用程式。本文著重於基礎設計原則:如何將 Spring beans 發布為 SCA 服務、如何在 Spring 應用程式中存取 SCA 服務與屬性。第二部分將深入探討進階特性,如多應用程式上下文處理與 Spring beans 中的 SCA 註解應用。

核心技術簡介

服務組件架構 (SCA)

SCA 提供基於面向服務架構 (SOA) 的程式設計模型,核心理念是將業務功能作為一系列服務提供,組合成滿足特定業務需求的解決方案。SCA 特色包括:

  • 服務組合與組件建立模型,支援重用現有應用程式
  • 彈性的組合、重用、技術與部署選擇,適合構建異構分散式系統
  • 支援多種實作語言 (Java POJO、EJB、Spring beans、BPEL、COBOL、C++、PHP 等) 與通訊機制
  • 簡化的組件程式設計模型

SCA 以「組合」描述應用程式結構與關聯,組合包含組件、服務、參考、屬性宣告及其關聯描述,可分組鏈接不同實作技術的組件,部署於 SCA 域中。

Spring Framework

Spring 是開源專案,旨在透過解決企業應用開發複雜性來提升 J2EE 環境適用性。其分層架構允許選擇性使用組件,為簡單 Java 物件 (POJO) 提供框架,使其透過包裝類與 XML 配置使用 J2EE 容器。Spring 常被稱為「輕量級容器」,更精確的比喻是「簡化開發的框架」。

Apache Tuscany

Apache Tuscany 致力於實作 SCA 規格 (含 Service Data Objects 與 Data Access Service 等相關規格)。遵循 OSOA 與 OASIS SCA Java 規格標準,為 SCA 運行時提供全面基礎設施。本文範例使用 Apache Tuscany V1.5 (撰寫時最新版)。

SCA 與 Spring 結合的優勢

Spring 與 SCA 共享許多設計原則。SCA 將 Spring 視為組件實作技術之一,SCA Spring Component Implementation Specification 定義了使用方式。兩者相似處在於:組件皆可包含對其他服務的參考與可配置屬性。差異在於:SCA 是跨語言的分散式組件架構,支援多種通訊機制。透過將 Spring beans 發布為可被其他組件存取的服務、提供關聯到遠端組件服務的參考,SCA 擴展了 Spring 組件功能。

有效整合策略:使用 Spring 構建「粗粒度」服務組件實作,引入 SCA 以發布服務、連接服務組件、處理異構與分散式系統。SCA 為 Spring 應用程式增加實用功能:

  • 遠端組件與多協議的擴展支援
  • 支援非 JVM 語言編寫的組件
  • 支援 WS-Policy 指定的安全性與交易策略
  • 測試便利性:SCA 組合可輕易切換到模擬配置進行測試

將 Spring 應用程式定義為 SCA 組件

在 Apache Tuscany 中,SCA 使用 Spring 作為組件在組合中的實作技術。透過 <implementation.spring> 元素在 SCDL (Service Component Definition Language) 中定義:

<composite xmlns="https://www.osoa.org/xmlns/sca/1.0"
 xmlns:tuscany="https://tuscany.apache.org/xmlns/sca/1.0"
 targetNamespace="https://calc"
 xmlns:c="https://calc"
 name="Calculator">

 <component name="CalculatorServiceComponent">
 <implementation.spring location="targetURI"/>
 </component>

</composite>

location 屬性可指定:

  • Spring 應用程式上下文檔案:<implementation.spring location="application-context.xml"/>
  • 目錄:<implementation.spring location="./spring"/> (需包含 META-INF/MANIFEST.MF,以 Spring-Context 標頭指定上下文路徑)
  • 存檔檔案:<implementation.spring location="spring.jar"/> (同樣需 MANIFEST.MF 與 Spring-Context 標頭)

基於 Spring 的 SCA 組件實作範例

以計算機組件為例:CalculatorComponent 依賴 AddComponent (JavaScript)、SubtractComponent (POJO)、MultiplyComponent (POJO)、DivideComponent (Groovy) 四個不同技術實作的組件。SCA 組合檔 calculator.composite 定義組件、服務、參考與關聯:

<composite xmlns="https://www.osoa.org/xmlns/sca/1.0"
 xmlns:t="https://tuscany.apache.org/xmlns/sca/1.0"
 targetNamespace="https://calc"
 xmlns:c="https://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>

注意:未明確宣告 <service> 的組件,SCA 運行時預設使用 binding.sca 發布;參考同樣預設使用 binding.sca 連接。

Spring 應用程式上下文定義

calculator-context.xml 定義業務邏輯與依賴:

<beans xmlns="https://www.springframework.org/schema/beans"
 xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
 xmlns:sca="https://www.springframework.org/schema/sca"
 xsi:schemaLocation="
 https://www.springframework.org/schema/beans
 https://www.springframework.org/schema/beans/spring-beans.xsd
 https://www.springframework.org/schema/sca
 https://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 bean 透過屬性引用組合中定義的 SCA 參考。若要將其發布為服務,需在上下文中宣告對應的 SCA 服務、參考與屬性。

顯式宣告 SCA 服務、參考與屬性

使用 Spring SCA 命名空間的自定義元素在上下文檔中宣告:

  • <sca:service>:控制哪些 Spring bean 發布為 SCA 服務,指定 name (對應組合中的服務名)、type (Java 介面完整名稱)、target (提供服務的 bean 名稱)
  • <sca:reference>:宣告對組合中其他 SCA 組件服務的依賴,需指定 name (對應組合中的參考名) 與 type
  • <sca:property>:宣告對 SCA 組件屬性的依賴,name 需與組合中的屬性名稱匹配

範例:

<beans ... xmlns:sca="https://www.springframework.org/schema/sca" ...>
 <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>

隱式宣告 SCA 服務、參考與屬性

SCA 運行時支援直接在 Spring 上下文中使用組合中定義的參考與屬性名稱作為 bean 參考,無需自定義命名空間元素。規則如下:

  • 參考:bean 屬性的 ref 直接設為組合中的參考名稱,類型由運行時從 bean 類定義內省驗證
  • 屬性:同樣直接引用組合中的屬性名稱
  • 服務:無顯式 <sca:service> 時,所有頂層 bean 均發布為 SCA 服務,服務名稱即 bean 名稱;內部 bean 與抽象 bean 排除;實作多介面的 bean 會以類本身作為單一服務介面發布

隱式宣告的限制場景

場景一:集合類型的隱式參考/屬性

在 <list>、<set>、 中使用隱式參考時,若集合泛型為 List<?> 等非具體類型,Tuscany 無法內省確切類型,導致注入失敗。建議改用顯式 <sca:reference> 指定 name 與 type。

場景二:建構子注入的隱式參考/屬性

Tuscany 不支援建構子注入的隱式參考。必須顯式宣告 <sca:reference>,並在 <constructor-arg> 中使用 index 與 type 屬性指定參考:

<bean id="Calculator" class="calculator.CalculatorServiceImpl">
 <constructor-arg index="0" type="calculator.AddService" ref="addService"/>
 <constructor-arg index="1" type="calculator.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 運行時中的應用程式上下文建立流程

Spring 核心單元為應用程式上下文,可形成階層結構 (子上下文可見父上下文 beans)。預設 Spring 容器啟動時驗證所有 bean 配置,但包含 SCA 參考/屬性的上下文需由 SCA 運行時先建立有效 bean。

Tuscany 運行時 (基於 Spring 2.5.5) 載入 <implementation.spring> 指定的目標上下文前,會:

  1. 內省目標上下文定義檔,識別其中宣告的 SCA 服務、參考、屬性
  2. 為所有 SCA 參考屬性建立 SCAParentApplicationContext,包含對應的 Spring beans
  3. 以 GenericApplicationContext 建立目標應用程式上下文,指定 SCAParentApplicationContext 為父上下文

此機制確保 Spring 容器驗證通過,同時 Tuscany 提供服務綁定基礎設施,依 SCDL 配置套用策略。

結語與展望

本文介紹了基於 Spring 應用程式設計開發 SCA 組件的方法,涵蓋顯式/隱式宣告 SCA 服務、參考、屬性,以及 SCA 運行時建立上下文的機制。SCA 與 Spring 結合形成強大組合:Spring 提供高效組件開發基礎設施,改善測試覆蓋與應用品質;SCA 提供 SOA 組件組裝建模、服務發布連接、異構分散式系統處理能力。

敬請期待第二部分:多應用程式上下文處理、Spring beans 中的 SCA 註解等進階主題。

SCA 組合圖

基於 Spring 的 CalculatorComponent

具有父上下文的 SCA 運行時

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved