目次


Spring フレームワークを利用して行う SCA コンポーネントの設計と開発

第 1 回 Spring、SCA、そして Apache Tuscany の 3 点セット

Comments

コンテンツシリーズ

このコンテンツは全#シリーズのパート#です: Spring フレームワークを利用して行う SCA コンポーネントの設計と開発

このシリーズの続きに乞うご期待。

このコンテンツはシリーズの一部分です:Spring フレームワークを利用して行う SCA コンポーネントの設計と開発

このシリーズの続きに乞うご期待。

はじめに

OSOA (Open SOA) イニシアチブが「Power Combination: SCA, OSGi and Spring」というタイトルのホワイト・ペーパーを公開して以来、この 3 つの技術の組み合わせに対する関心が高まっています。こうした基盤技術の商用実装である Spring Dynamic Module では、Spring と OGSi とを組み合わせています。Spring Bean は SCA (Service Component Architecture) コンポーネントの実装として使用することができます。また、Apache Tuscany の Java 実装は Apache の OSGi フレームワーク (Felix) を利用して、その上に構築されたものです。

このシリーズでは、Spring フレームワークと Apache Tuscany SCA Java ランタイムを使って SCA コンポーネントを設計、作成する方法を学びます。サンプルやコード・スニペットを見ると、SCA と Spring とを組み合わせるメリットが理解しやすくなるはずです。またこのシリーズでは、SCA と Spring とを組み合わせて分散サービス・アプリケーションを作成する方法についても学びます。

今回の記事では、Spring を使って SCA コンポーネントを作成する際に知っておく必要のある、いくつかの基本的な設計原則を説明します。そして Spring の Bean を SCA サービスとして公開する方法、さらには Spring アプリケーションの中で SCA のサービスとプロパティーにアクセスする方法を学びます。

第 2 回では、SCA によって複数のアプリケーション・コンテキストを処理する方法や、Spring Bean の中で SCA アノテーションを使用する方法などの高度な機能について学びます。

まずは、サンプルのソース・コードをダウンロードしてください。このサンプルは Apache Tuscany ランタイムで実行するように設計されていますが、これらの例は SCA コンポーネントの作成方法を説明するためのものではありません。この記事では、SCA コンポーネントを実装する技術としての Spring アプリケーションの使い方に焦点を当てます。

プログラム

この記事では、以下のプログラムについて説明します。

SCA
SCA は、SOA (Service-Oriented Architecture) に基づいてアプリケーションやソリューションを作成するためのプログラミング・モデルです。SCA は、ビジネス機能は一連のサービスとして提供されるという概念に基づいており、それらのサービスを組み合わせることで、特定のビジネス・ニーズに対応するソリューションが作成されます。このようにして作成された複合アプリケーションには、そのアプリケーション用に作成された新しいサービスや、既存のシステムのビジネス機能、さらにはその複合アプリケーションの一部として再利用されるアプリケーションなどが含まれます。SCA には以下の特徴があります。
  • SCA コンポジットの中にある既存のアプリケーション機能を再利用することを含め、SCA はサービスの合成やサービス・コンポーネントの作成のためのモデルを提供します。
  • SCA によって、合成、再利用、技術、デプロイメントにおける柔軟な選択肢が提供されます。そのため、SCA は異種混成の分散システムを構築するための理想的な環境です。
  • SCA は複数の実装言語と通信メカニズムをサポートしています。
  • SCA では、単純化されたコンポーネント・プログラミング・モデルを使ってビジネス・サービスを実装することができ、そのためにさまざまな技術 (Enterprise JavaBeans、Java POJO、Spring Bean、BPEL プロセス、COBOL、C++、PHP など) を使用することができます。
Spring フレームワーク
Spring フレームワークはオープンソースのプロジェクトであり、通常、Spring と呼ばれます。Spring では、エンタープライズ・アプリケーション開発の複雑さに対応することで J2EE 環境を使いやすいものにします。J2EE アプリケーション開発に必要なものが揃ったフレームワークである Spring には、アーキテクチャーが階層化されているという大きなメリットがあるため、どの Spring コンポーネントを使用するのかを選択することができます。また、Spring は単純な Java オブジェクトのためのフレームワークであるため、Java オブジェクトは XML による構成とラッパー・クラスを使うことで J2EE コンテナーを使用することができます。Spring の目標は、開発の生産性とランタイム・パフォーマンスを高めることによって、プロジェクトに大きなメリットをもたらすこと、そしてテスト・カバレッジとアプリケーション品質を改善することです。Spring は軽量コンテナー環境と表現されることがよくありますが、開発を単純化するためのフレームワークと呼んだ方がおそらく適切です。
Apache Tuscany
オープンソースの Apache Tuscany プロジェクトは、SCA 仕様 (そして SDO (Service Data Objects) や DAS (Data Access Service) など、他の SCA 仕様) を実装することのみを目標にしています。Apache Tuscany は SCA ラインタイムの完全な基盤となります。この SCA ラインタイムは OSOA (Open Service-Oriented Architecture) の仕様や、グローバルな情報社会のための進化し続けるオープン・スタンダードである OASIS SCA Java の仕様に準拠します。この記事で紹介する例では、この記事の執筆時点で最新の V1.5 を使用しています。これらのサンプル・アプリケーションを実行するためには、Apache Tuscany SCA Java 実装のバイナリー・ディストリビューションをダウンロードする必要があります。

SCA アセンブリー・モデル

SCA の基本的な成果物は、SCA の構成単位であるコンポーネントです。コンポーネントは、ある 1 つの実装を構成したインスタンスで構成されます。この場合の実装というのは、ビジネス機能を提供するプログラム・コードです。ビジネス機能は、他のコンポーネントがサービスとして使用するために提供されるものです。実装は他のコンポーネントが提供するサービスに依存する可能性があり、こうした依存関係は参照と呼ばれます。

実装にはプロパティーを設定することが可能で、プロパティーに設定されたデータ値によってビジネス機能の動作が変わってきます。コンポーネントが実装を構成する方法としては、プロパティーに対して値を設定する方法や、他のコンポーネントが提供するサービスに対して参照をワイヤリングする方法などが使われます。同じ実装を複数のコンポーネントが使用、構成することができますが、各コンポーネントはその実装を異なる方法で構成します。

SCA では、以下のことが可能です。

  • さまざまな実装技術を使用することができます (Java POJO、EJB、Spring Bean、BPEL プロセス、COBOL、C++ など)。
  • スクリプト言語を使用することができます (PHP や JavaScript など)。
  • 宣言型の言語を使用することができます (XQuery や SQL など)。

SCA では、アセンブリーの中でのコンポジット (Composite) と呼ばれるアプリケーション本体と、そのコンポジット同士の関係を表現します (図 1)。コンポジットには、コンポーネント (Component)、サービス (Service)、参照 (Reference)、プロパティー (Properties) 宣言、そしてこれらの要素間の接続を記述するワイヤー (Wire) が含まれます。コンポジットは、さまざまな実装技術で作成されたコンポーネント同士をグループ化、および接続することで、各ビジネス・タスクが必要とする技術を使用できるようにします。コンポジットは SCA ドメインの中にデプロイされます。

図 1. SCA コンポジットの構成図
SCA コンポジットの構成図
SCA コンポジットの構成図

SCA アセンブリー・モデルを構成する要素には、(サービス・コンポーネントのアセンブリーを含むコンポジットの面から) SCA ドメインの構成を定義する一連の成果物と、コンポジット同士の関係を表す接続および関連成果物があります。この詳細は SCA アセンブリー・モデルの仕様に説明されています (「参考文献」を参照)。

SCA と Spring とを組み合わせるメリット

Spring フレームワークと SCA には設計の原則に多くの共通点があります。SCA は Spring を、SCA コンポーネントの実装技術として使用することができるパートナーと見なします。SCA Spring コンポーネント実装仕様には、この観点から Spring を使用する方法が定義されています。

Spring Bean と同じように、SCA コンポーネントには他のコンポーネントが提供するサービスへの参照と、外部から設定することが可能なプロパティーを含めることができます。Spring とは対照的に、SCA は言語に依存しない分散コンポーネント・アーキテクチャーであり、コンポーネント間で複数の通信メカニズムを使用することができます。また SCA を使用すると、Spring コンポーネントの機能を拡張することもできます。そのためには、他のリモート・コンポーネントがアクセスするサービスとして Spring Bean を公開するとともに、他の (場合によってはリモートの) コンポーネントのサービスにワイヤリングされたサービス参照を Spring Bean に提供します。

SCA と Spring を効果的に組み合わせるためには、まず Spring を使って「粒度の粗い」サービス・コンポーネントの実装を作成し、次に SCA を使ってサービスを公開し、サービス・コンポーネント同士をワイヤリングすることで、異種混成の分散型システムを扱うようにします。Spring を使って実装されたアプリケーションには、SCA を使用することで以下の有用なメリットが実現されます。

  • リモート・コンポーネントや複数のプロトコルを使うように拡張することができます。
  • JVM でサポートされている以外のさまざまなプログラミング言語で作成されたコンポーネントをサポートすることができます。
  • セキュリティーやトランザクションなどの機能に対し、WS-Policy で規定されるポリシーを適用することができます。

コンポーネントを容易にテストできることは Spring の大きな特徴の 1 つです。コンポーネントには、API や注入手法がないため、テストは単純なモック・オブジェクトを使って行います。これを SCA がサービスの領域で補完します。なぜなら、サービス・コンポーネントを包含する SCA コンポジットは、テスト用のモック構成に容易に切り換えられるからです。

Spring アプリケーションを SCA コンポーネントとして定義する

Apache Tuscany の SCA 実装では、SCA は Spring を SCA コンポーネントの実装技術として 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> 要素の location 属性によって、ターゲット URI がアーカイブ・ファイル (.jar) またはディレクトリーを指すように、または Spring アプリケーションのコンテキスト・ファイルを直接指すように指定することができます。

下記のリストは、<implementation.spring> の location 属性に対するターゲット URI の指定方法として考えられる例を示しています。

Spring アプリケーションのコンテキスト・ファイルを指定する
<implementation.spring location="application-context.xml"/>
ディレクトリーを指定する
<implementation.spring location="./spring"/>

ターゲット URI によって指定されるリソースは、Spring 関連のすべてのファイルがある、spring という名前のディレクトリーです。spring ディレクトリーの配下には、META-INF/MANIFEST.MF ファイルが存在していなければなりません。このファイルは Spring-Context ヘッダーを Spring-Context ::= <path> というフォーマットで使用することで、コンテキスト構成ファイルへのパスを指定します (path は spring ディレクトリーに対する相対パスです)。MANIFEST.MF ファイルがない場合、あるいは MANIFEST ファイルの中に Spring-Context ヘッダーがない場合には、デフォルトの動作として、ターゲットの spring ディレクトリー内の META-INF/spring ディレクトリーの中にある application-context.xml ファイルを使用してアプリケーション・コンテキストが作成されます。
アーカイブ・ファイルを指定する
<implementation.spring location="spring.jar"/>

ターゲット URI によって指定されるリソースは、Spring 関連のすべてのファイルがある spring.jar というアーカイブ・ファイルです。spring.jar アーカイブ・ファイルの中には META-INF/MANIFEST.MF ファイルが存在していなければなりません。このファイルは Spring-Context ヘッダーを Spring-Context ::= <path>. というフォーマットで使用することで、コンテキスト構成ファイルへのパスを指定します (path は spring.jar アーカイブの中あるファイルを指します)。MANIFEST.MF ファイルがない場合、あるいは MANIFEST ファイルの中に Spring-Context ヘッダーがない場合には、デフォルトの動作として、ターゲットの spring.jar アーカイブ・ファイルの META-INF/spring ディレクトリーの中にある application-context.xml ファイルを使用してアプリケーション・コンテキストが作成されます。

Spring ベースの SCA コンポーネント

コンポーネントの実装のビジネス機能は、他のコンポーネントがこの機能をサービスとして使用するために提供されます。実装は、他のコンポーネントが提供するサービスに依存し、これらの依存関係は参照と呼ばれます。また、実装には、ビジネス機能の動作に影響を与えるデータ値として設定可能なプロパティーを含めることができます。以下のサンプルでは、Spring Bean を SCA サービスとして提供する方法と、Spring アプリケーションのコンテキストの中で SCA 参照と SCA プロパティーを構成する方法について説明します。

サンプル

CalculatorComponent の例を使いましょう (図 2)。CalculatorComponent は、他のコンポーネント (AddComponentSubtractComponentMultiplyComponentDivideComponent) に対する外部依存関係を使って必要な機能を実現します。この例では、CalculatorComponent のビジネス機能の実装には Spring Bean が使われており、AddComponent には JavaScript が、SubtractComponentMultiplyComponent には単純な POJO が、DivideComponent には Groovy スクリプトが使われています。

図 2. Spring ベースの CalculatorComponent
Spring ベースの CalculatorComponent
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 によって CalculatorComponent を定義し、また他の 4 つのサービス (AddComponentSubtractComponentMultiplyComponentDivideComponent) に対する CalculatorComponent の依存関係を <reference> 要素を使って定義します。4 つのサービスは異なる技術を使って実装されています。AddComponent は、入力として指定される 2 つの数字の和を返す addService の実装を提供します。同様に、SubtractComponent は 2 つの数字の差を返す subtractService の実装を提供します。MultiplyComponent は 2 つの数字の積を返す multiplyService の実装を提供します。DivideComponent は 2 つの数字の商を返す divideService の実装を提供します。

おそらく読者の皆さんは、calculator.composite の中で (CalculatorComponent に対して CalculatorService を公開することを宣言しているのとは違って)、AddComponentSubtractComponentMultiplyComponentDivideComponent は明示的に <service> 要素を使用してサービスを公開しているわけではないことに気付いたのではないでしょうか。こうした場合、つまり SCA コンポーネントが <service> 要素を使用して明示的にサービスを公開しているわけではない場合には、SCA ランタイムはデフォルトで、binding.sca というデフォルトのバインディングを使ってアクセスされるものとしてコンポーネントを公開します。同様に CalculatorComponent では、これらのコンポーネントへの参照に対して特定のバインディング情報を指定する必要はありません。SCA ランタイムがデフォルトのバインディング (binding.sca) を提供し、これらのコンポーネントをワイヤリングします。SCA アセンブリー・モデルの仕様には binding.sca の詳細が説明されています。

この例では、CalculatorComponent は Spring Bean を使用してビジネス・ロジックを定義する Spring アプリケーションです。重要な点として、SCA に必要な依存関係を Spring アプリケーションのコンテキスト定義ファイルの中で適切に宣言することを忘れないようにする必要があります。

そこで、calculator-context.xml という、Spring アプリケーションのコンテキスト定義ファイルを作成します。リスト 3 に示すように、このファイルは必要な機能を実現するための Bean とその依存関係を宣言し、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 は必要な依存関係を Bean のプロパティーとして設定することにより、CalculatorComponent に対するビジネス・ロジックを定義しています。Spring Bean の場合、各プロパティーに定義されているのは、コンテナー内の別の Bean を設定または参照するための、実際の値の定義です。この例では、Calculator Bean は、SCA コンポジットの中にある SCA コンポーネントが提供するさまざまな SCA サービスに依存しています。そのため、calculator.composite で定義される SCA 参照を参照するように、SCA プロパティー (ref 属性の値) を設定する必要があります。目標は CalculatorComponent をサービスとして公開することなので、calculator.composite で定義される SCA サービスに対して、どの Bean を公開する必要があるのかも宣言する必要があることを忘れないでください。

Spring コンポーネントの実装仕様と Apache Tuscany SCA ランタイムを使用すると、SCA 参照と SCA プロパティーを Bean のプロパティーとして宣言することができます。またこの Bean を SCA サービスとして公開することを (明示的あるいは暗黙的に) 宣言することもできます。これについては、以下で説明します。

SCA サービス、SCA 参照、SCA プロパティーを明示的に宣言する

SCA Spring コンポーネント実装仕様と Apache Tuscany SCA ランタイムを使用すると、SCA サービス、SCA 参照、SCA プロパティーを、Spring アプリケーションのコンテキスト・ファイルの中で、Spring の SCA スキーマで定義されるカスタムの SCA 名前空間要素を使って宣言することができます。カスタムの SCA 名前空間要素を使用すると、Spring Bean を SCA サービスとして宣言することができ、また SCA コンポーネントを定義することで得られる SCA サービスと SCA プロパティーに対する参照を定義することができます。Spring アプリケーションのコンテキスト・ファイル内にある SCA 名前空間要素を使用する方法を、SCA サービス、SCA 参照、SCA プロパティーの「明示的な宣言」と表現します。

アプリケーションのコンテキスト・ファイルの中で SCA サービス、SCA 参照、SCA プロパティーを宣言するための、カスタムの SCA 名前空間要素について以下で説明します。

<sca:service>
この要素を使用すると、どの Spring Bean を SCA サービスとして公開するかを制御することができます。SCA ランタイムは SCDL による構成を基に、適切なサービス・バインディングを作成し、また必要なポリシーをこれらのサービスに適用します。
<sca:reference>
この要素を使用すると、Spring アプリケーションのコンテキストの依存関係を、コンポジットの中の他の SCA コンポーネントが提供するサービスに対して宣言することができます。SCA ランタイムは SCDL による構成を基に、適切な参照バインディングを作成し、また必要なポリシーをこれらのサービスに適用します。
<sca:property>
この要素を使用すると、Spring アプリケーションのコンテキストの依存関係を、SCA コンポーネントの実装が提供する設定可能なプロパティーに対して宣言することができます。<sca:property> 要素の name 属性は、コンポジットに含まれるコンポーネントの SCA プロパティーとしてコンポジットの中で宣言されている名前と一致する必要があります。

calculator-context.xml (リスト 3) の中で、カスタムの SCA 名前空間要素を使って SCA サービス、SCA 参照、SCA プロパティーを宣言します (リスト 4)。

リスト 4. 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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://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>

<sca:service> 要素はリスト 4 に示すように、ターゲットの Calculator Bean から SCA サービスとして CalculatorService を提供すると宣言しています。この要素には name 属性が必要であり、この属性の値は calculator.composite の CalculatorComponent に対して定義される <service> 要素の名前と同じ値である必要があります。また type 属性も必要であり、この属性によってサービスのタイプを Java クラスの完全修飾名として宣言する必要があります。さらに target 属性も必要であり、この属性にはアプリケーション・コンテキストの中にある <bean/> 要素の名前が指定されている必要があります (<bean/> 要素は、この <sca:service> 要素が宣言するサービスを提供します)。

リスト 4 の <sca:reference> 要素は、このアプリケーション・コンテキストの依存関係を、コンポジットの中にある他の SCA コンポーネントが提供するサービスに対して宣言します。この例では、Calculator Bean は SCA サービス (AddComponentSubtractComponentMultiplyComponentDivideComponent) に依存しています。これらの依存関係は <sca:reference> 要素を使って宣言されます。この要素には name 属性が必要であり、この属性の値は calculator.composite の CalculatorComponent で定義される <reference> 要素の名前と同じ値である必要があります。また type 属性も必要であり、この属性によってサービスのタイプを Java クラスの完全修飾名として宣言する必要があります。calculator.composite の CalculatorComponent の中にある各 <reference> 要素に対して、それと等価な <sca:reference> 要素が Spring のアプリケーション・コンテキストの中で宣言されます。

同様に、<sca:property> 要素を使用すると、このアプリケーション・コンテキストの依存関係を、calculator.composite の CalculatorComponent が提供する SCA プロパティーに対して宣言することができます。<sca:property> 要素には name 属性が必要であり、この属性の値は calculator.composite (リスト 2) の CalculatorComponent に対して定義される <property/> 要素の名前と同じ値である必要があります。また type 属性も必要であり、この属性によってプロパティーのタイプを Java クラスの完全修飾名として宣言する必要があります。

SCA サービス、SCA 参照、SCA プロパティーを暗黙的に宣言する

SCA Spring コンポーネント実装仕様と Apache Tuscany SCA ランタイムを使用すると、SCA サービス、SCA 参照、SCA プロパティーを Spring アプリケーションのコンテキスト・ファイルの中で直接宣言することができ、Spring の SCA スキーマで定義されるカスタムの SCA 名前空間要素を使用する必要がありません。Spring アプリケーションのコンテキスト・ファイル内にある SCA 参照と SCA プロパティーを直接使用し、カスタムの SCA 名前空間を使わない方法を、SCA サービス、SCA 参照、SCA プロパティーの「暗黙的な宣言」と表現します。リスト 3 の calculator-context.xml はその一例です。

SCA 参照は calculator.composite ファイル (リスト 2) の中で、addServicesubtractServicemultiplyServicedivideService のような名前で定義されており、Spring アプリケーションのコンテキスト (リスト 3) の中で、この SCA 参照を Bean 参照として直接使用することができます。calculator.composite の中で定義される SCA 参照を Calculator Bean のプロパティーが参照するように、(ref 属性の値を) SCA 参照名を使って直接設定することができます。このような場合、Bean 参照のタイプは Tuscany ランタイムによって Bean クラスの定義からイントロスペクションされ、コンポジットの中で定義される SCA 参照のタイプに対して検証と突き合わせが行われます。

同様に、SCA コンポジットの中で定義される SCA プロパティーを、Spring アプリケーションのコンテキストの中で Bean 参照として直接使用することができます。calculator.composite の中で定義される SCA プロパティーを Bean のプロパティーが参照するように、SCA プロパティーの名前を使って (ref 属性の値を) 設定します。

アプリケーションのコンテキストの中に明示的な <sca:service> 要素がない場合には、最上位レベルの Bean はすべて SCA サービスとして公開され、サービスの名前には Bean の名前が使われます。暗黙的なサービスを作成する場合には、内部 Bean や抽象 Bean は考慮されません。Spring Bean の実装クラスが複数のインターフェースを実装している場合には、これらの Bean は 1 つのサービスとして公開される場合と、複数のサービスとして公開される場合があります。明示的に <sca:service> 要素を使用する場合、各 <sca:service> 要素は同じ <bean> 要素を参照しますが、type 属性には Bean が提供するインターフェースのうちの 1 つのみが使用されます。暗黙的にサービスを作成する場合には、Bean を 1 つのサービスとして公開します (そのためには Bean クラス自体をサービスに対するインターフェースとして宣言します)。

Apache Tuscany SCA ラインタイムでは暗黙的に SCA サービス、SCA 参照、SCA プロパティーを使用することができますが、以下に示すように、暗黙的な宣言では適切に動作しないケースがいくつかあります。

ケース 1. 暗黙的な SCA 参照と SCA プロパティーをコレクションに対して使用する場合

Spring では、<list/><set/><map/><props/> 要素を使用すると、それぞれ Java の Collection 型の ListSetMapProperties のプロパティーと引数を定義し、設定することができます。Bean を定義する例 (リスト 5) は、Spring の <list/><set/><map/> 要素の中で SCA 参照と 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 は Generics として宣言され、コレクションの中のすべての種類の Java クラスを受け付けます。

リスト 6. someList プロパティーに対する Bean の実装
private List<?> someList;
    
public List<?> getSomeList() {
return someList;
}
    
publicvoid setSomeList(List<?> someList) {
this.someList = someList;
}

こうしたケースでは、Apache Tuscany ラインタイムは、このコレクションに必要な SCA 参照オブジェクトのタイプ (mySCAReference1mySCAReference2mySCAReference3 のいずれか) を正確にイントロスペクションすることができません。必要な SCA 参照を注入しようとしても失敗します。同じことは、コレクションの中のすべての種類の Java クラスを受け付けるように someMap プロパティーと someSet プロパティーを宣言した場合にも当てはまります。このような場合には、<sca:reference> 要素と、この要素に必要な name 属性と type 属性を使って、必ず SCA 参照を明示的に宣言することをお勧めします。

ケース 2. 暗黙的な SCA 参照と SCA プロパティーをコンストラクターの注入に使用する場合

Spring のコンストラクター注入を使用すると、クラス・コンストラクターを使って依存関係を注入することができます。曖昧さを減らすために、Spring では、Bean の実装の中に複数のコンストラクターが定義されている場合には、<constructor-arg> 要素に対して必ず index 属性と type 属性を適切に使用するように推奨しています。

Tuscany でも、コンストラクターを注入するすべてのケースで (たとえ Bean のコンストラクターが 1 つのみの場合でも)、<constructor-arg> 要素に対して index 属性と type 属性を使用するように、また従属する SCA 参照を明示的に宣言するように推奨しています。

例えば、Calculator Bean に必要な依存関係 (必要な SCA 参照) を、コンストラクターを使って注入するとします。この場合にはリスト 7 のように Bean を定義する必要があります。Tuscany のコンストラクター注入では、SCA 参照と 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 を参照しているかどうかの検証も含まれます。Spring アプリケーション・コンテキストが SCA 参照や SCA プロパティーへの参照を含む場合には、その Spring アプリケーション・コンテキストの中で使われるすべての SCA 参照と SCA プロパティーに対する有効な Bean を、SCA ランタイムが作成します。次に Spring コンテナーは、それらの Bean を検証し、アプリケーション・コンテキストを適切にロードします。図 3 はその一例です。

図 3. 親コンテキストを持つ SCA ランタイム
親コンテキストを持つ SCA ランタイム
親コンテキストを持つ SCA ランタイム

Tuscany ランタイムは Spring Binary V2.5.5 を使用してターゲットのアプリケーション・コンテキストをロードし、実行します。このアプリケーション・コンテキストは、calculator.composite ファイル (リスト 2) の中で定義される <implementation.spring> 要素の location 属性で指定されています。ターゲットのアプリケーション・コンテキストがロードされる前に、Tuscany ランタイムは以下の処理を試みます。

  • ターゲットのアプリケーション・コンテキストの定義ファイルにイントロスペクションを実行し、Spring アプリケーションのコンテキストの中で SCA サービス、SCA 参照、SCA プロパティーが宣言されているかどうかを判断します。
  • ターゲットのアプリケーション・コンテキストの中で宣言されているすべての SCA 参照と SCA プロパティーに対し、適切な Spring Bean を使って SCAParentApplicationContext を作成します。

この例の場合には、calculator-context.xml ファイル (図 3) の中で宣言されたすべての SCA 参照 (addServicesubtractServicemultiplyServicedivideService) に対して、適切な Spring Bean を使って SCAParentApplicationContext が作成されています。その後で、SCAParentApplicationContext を親として宣言することによって、org.springframework.context.support.GenericApplicationContext を使ってターゲットのアプリケーション・コンテキストが作成されています。

Tuscany ランタイムは、適切なサービス・バインディングを作成するために必要な基盤でもあり、また SCDL による構成を基に Spring Bean を使って実装されたサービスに対し、必要なポリシーを適用します。

まとめ

この記事では、Spring ベースのアプリケーションを使って SCA コンポーネントを設計し、作成する方法を学びました。これで読者の皆さんは、カスタムの SCA 名前空間要素を使って Spring アプリケーションのコンテキストの中で SCA サービス、SCA 参照、SCA プロパティーを明示的に宣言することができ、また Spring アプリケーションのコンテキストの中で SCA 参照と SCA プロパティーを直接宣言することができます。また、SCA コンポーネントに対するターゲットのアプリケーション・コンテキストを SCA ランタイムがどのように作成するかについても学びました。この記事では例を使いながら、アプリケーションのコンテキストの中で SCA 参照と SCA プロパティーを暗黙的に使用する場合の制約についても簡単に触れました。

SCA と Spring との組み合わせは強力です。Spring は、高い生産性とランタイム・パフォーマンスでコンポーネントを作成するための基盤となり、テスト・カバレッジとアプリケーションの品質も向上させることができます。一方の SCA は SOA ベースでのコンポーネントのアセンブルとモデリングに必要な基盤となっており、SCA を利用することでコンポーネントがサービスの公開や、サービス・コンポーネント同士のワイヤリング、さらには異種混成の分散システムへの対応を行えるようになります。

第 2 回では、SCA によって複数のアプリケーション・コンテキストを処理する方法や、Spring Bean の中で SCA アノテーションを使う方法など、高度な機能について説明します。第 2 回にご期待ください。


ダウンロード可能なリソース


関連トピック

  • SCA の標準に基づいて SOA 開発と管理を行うための総合的なインフラ、Apache Tuscany の資料を読んでください。
  • Spring フレームワークのすべてについて学んでください。
  • OSOA (Open Service-Oriented Architecture) プロジェクトについての資料を読んでください。
  • SCA のための CSA 技術委員会、OASIS SCA Java について学んでください。
  • Introducing SCA」は、SCA の基本、SCA コンポーネント、ポリシー、そしてそれらの全体的な関係について説明しています。
  • ホワイト・ペーパー「Power Combination, SCA, OSGi and Spring」は、SCA、OSGi、Spring を相互補完的な技術と見なせる理由、SCA、OSGi、Spring の組み合わせによる可能性とその方法、SCA、OSGi、Spring を組み合わせるメリット、この組み合わせを実現するために続けられている活動、などを検証しています。
  • Spring Dynamic Module を利用すると、OSGi フレームワークで実行する Spring アプリケーションを容易に作成することができます。
  • SCA アセンブリー・モデルの仕様 (SCA アセンブリー・モデルに関する OSOA 仕様) を読んでください。
  • SCA Spring コンポーネント実装仕様について学んでください。
  • Spring SCA スキーマについて調べてみてください。Spring SCA スキーマは SCA Spring コンポーネント実装仕様に基づく OSOA 仕様の一部であり、Spring で SCA 要素を宣言するため方法が規定されています。
  • developerWorks podcasts ではソフトウェア開発者のための興味深いインタビューや議論を聞くことができます。
  • developerWorks を Twitter でフォローしてください。
  • developerWorks の Open source ゾーンをご覧ください。オープンソース技術を使った開発や、IBM 製品でオープンソース技術を使用するためのハウ・ツー情報やツール、プロジェクトの更新情報など、豊富な情報が用意されています。また最も人気の高かった記事とチュートリアルの一覧もご覧ください。
  • OSGi R4 サービス・プラットフォームを実装するためのコミュニティー活動の成果、Apache Felix を入手してください
  • Apache Tuscany SCA Java 実装のバイナリー・ディストリビューションをダウンロードしてください。
  • IBM 製品の試用版をダウンロードするか、あるいは IBM SOA Sandbox のオンライン試用版で、DB2®、Lotus®、Rational®、Tivoli®、WebSphere® などが提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。

コメント

コメントを登録するにはサインインあるいは登録してください。

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Open source, SOA and web services
ArticleID=442430
ArticleTitle=Spring フレームワークを利用して行う SCA コンポーネントの設計と開発: 第 1 回 Spring、SCA、そして Apache Tuscany の 3 点セット
publish-date=10062009