サンプル解説

それでは、Calculatorサンプルを利用してTuscany上で作成するSCAアプリケーションについて説明しよう。

Calculatorは1つのコンポジットからなるSCAアセンブリであり、図にすると以下のようになる。

図6: CalculatorサンプルのSCAアセンブリを示した図

コンポジットCalculatorComposite内に全てのコンポーネントが格納されており、コンポーネントCalculatorServiceComponentがその他の全コンポーネントを参照しているのがお分かりだろう。この構造をSCDLで記述したものが「calculator/src/main/resources/META-INF/sca/default.scdl」である。以下、ファイル内にコメントを追加したものを示す。

<!-- コンポジットの定義。名前はCalculatorComposite -->
<composite name="CalculatorComposite" xmlns="http://www.osoa.org/xmlns/sca/1.0">

    <!-- コンポジット外部に公開するサービス「CalculatorService」-->
    <service name="CalculatorService">
        <!-- Javaインタフェースをサービスのインタフェースとして使用 -->
        <interface.java interface="calculator.CalculatorService"/>
        <!-- コンポーネント「CalculatorServiceComponent」を参照 -->
        <reference>CalculatorServiceComponent</reference>
    </service>

    <!-- コンポーネント「CalculatorServiceComponent」 -->
    <component name="CalculatorServiceComponent">
        <!-- Javaの実装クラスの指定 -->
        <implementation.java class="calculator.CalculatorServiceImpl"/>

        <!-- 他のコンポーネントを参照している -->
        <reference name="addService">AddServiceComponent</reference>
        <reference name="subtractService">SubtractServiceComponent</reference>
        <reference name="multiplyService">MultiplyServiceComponent</reference>
        <reference name="divideService">DivideServiceComponent</reference>
    </component>

    <!-- コンポーネント「AddServiceComponent」-->
    <component name="AddServiceComponent">
        <implementation.java class="calculator.AddServiceImpl"/>
    </component>
    <!-- コンポーネント「SubtractServiceComponent」-->
    <component name="SubtractServiceComponent">
        <implementation.java class="calculator.SubtractServiceImpl"/>
    </component>
    <!-- コンポーネント「MultiplyServiceComponent」-->
    <component name="MultiplyServiceComponent">
        <implementation.java class="calculator.MultiplyServiceImpl"/>
    </component>
    <!-- コンポーネント「DivideServiceComponent」-->
    <component name="DivideServiceComponent">
        <implementation.java class="calculator.DivideServiceImpl"/>
    </component>
</composite>

では、このサンプルの核となるコンポーネントCalculatorServiceComponentの実装クラス「calculator.CalculatorServiceImpl」をざっと見てみよう。

以下のコードは、クラスcalculator.CalculatorServiceImplの中から注意すべき部分を抜き出したものだ。

@Scope("MODULE") ・・・(1)
public class CalculatorServiceImpl implements CalculatorService ・・・(2)
{
    private AddService addService;

    ・・・略・・・

    @Reference ・・・(3)
    public void setAddService(AddService addService) {
        this.addService = addService;
    }

    ・・・略・・・

    public double add(double n1, double n2) {
        return addService.add(n1, n2); ・・・(4)
    }

    ・・・略・・・
}

括弧書きの数字を付けた部分は、以下のようになっている。

(1) コンポーネントのインスタンスが共有されるスコープを指定している。現在のTuscanyにおけるJava APIは、SCA仕様バージョン0.95を基にしているため"MODULE"というスコープ名が使用されている。バージョン1.0では"COMPOSITE"となり、コンポジット内で1つのコンポーネントインスタンスが共有されるという設定になる。ちなみに、スコープには他に"STATELESS"(共有されない)、"REQUEST"(1つのリクエスト内で共有される)、"CONVERSATION"(対話中継続される)がある

(2) CalculatorServiceというインタフェースを実装していることに注目。Tuscanyは、指定されたインプリメンテーションが実装しているインタフェースを、自動的にコンポーネントのサービスインタフェースとする。したがって、CalculatorServiceComponentが提供するサービスのインタフェースはCalculatorServiceである

(3) SCDLで定義していたaddServiceという名前のリファレンスが、インプリメンテーション上ではSetter Injectionを利用したコードとなり、他のサービスへの参照を取得できている。その際利用するのは@Referenceというアノテーションであり、このアノテーションが付加されたフィールド、コンストラクタ、Setterメソッドが依存性注入の対象となる

(4) AddServiceのメソッドを利用し、数値の合計を求めている

大体の雰囲気はつかめただろう。重要なのは(2)と(3)であり、SCDLと実装コードの接点になっている部分でもあるので、よく理解していただきたい。