(9)【ServiceLocator】役割と実装例

com.adobe.cairngorm.business.IServiceLocator;
com.adobe.cairngorm.business.ServiceLocator;の説明です。(Cairngorm2.1)

今回は残念ながら疑問が残ったままです↓⇒解決しました!

役割

サービスクラスインスタンスを提供(管理)する。

IServiceLocatorインターフェイスでは、以下のメソッドを定義しています。

  // 引数のservice idのRemoteObjectを返す。
  getRemoteObject( serviceId : String ) : RemoteObject;
  // 引数のservice idのHTTPServiceを返す。
  getHTTPService( serviceId : String ) : HTTPService;
  // 引数のdestination idのWebServiceを返す。
  getWebService( destinationId : String ) : WebService;
  // 引数のdestination idのConsumerを返す。
  getConsumer( destinationId : String ) : Consumer;
  // 引数のdestination idのProduceを返す。
  getProducer( destinationId : String ) : Producer;
  // 引数のdestination idのDataServiceを返す。
  getDataService( destinationId : String ) : DataService;
  // プロキシを使用するサービスか遠く離れた終点へのサードパーティ製アダプターが代わりにsetRemoteCredentialsに必要とする注意。
  //  すべての登録されたサービスに証明書を設定してください。 
  setCredentials( username : String,   password : String ) : void;
  // ?
  logout() : void;

ServiceLocatorクラスはIServiceLocatorインターフェイスを実装しています。
Singletonで作成されており、staticなgetInstance()メソッドを使用してインスタンスを取得します。

ServiceLocatorには、
あらかじめ作成しておいた「タグをルートとしたmxmlファイル」のサービスが
(ApplicationMXMLにてインスタンスを生成していて、かつSingletonなので)登録されており、
Delegateなどのビジネスロジッククラスは、
そのサービスのID(Service mxmlで定義する)を引数としてインスタンスを取得・実行させます。

具体的には、ビジネスロジックは以下の記述によってサービスクラスのインスタンスを取得します。

this.service = ServiceLocator.getInstance().getRemoteObject("loginService");

実装例
Serviceを取り扱う場合は、以下の操作を行います。
1)サービス用mxmlファイルを作成
S2Flex2の例

<cairngorm:ServiceLocator xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:cairngorm="com.adobe.cairngorm.business.*" xmlns:s2="http://www.seasar.org/s2flex2/mxml" >
    <s2:S2Flex2Service id="loginService" destination="loginService" gatewayUrl="http://localhost:8080/login/gateway"
        result="event.token.resultHandler( event );" fault="event.token.faultHandler( event );" showBusyCursor="true" />
</cairngorm:ServiceLocator>

2)アプリケーションmxml(メインのmxml)にてサービスを記述

<mx:Application xmlns:service="sample.service.*" ・・・>
    ・・・
    <service:LoginService id="loginService" />

3)ビジネスロジックで使用する

・・・
service = ServiceLocator.getInstance().getRemoteObject("loginService");
・・・

※RemoteObjectなどを使用する場合は、別途FlexDataService2をインストールする必要があります。

さて、今回はかなり疑問が残ってしまいました。
ServiceLocatorは、どうやってサービスIDを保持するのでしょうか??
cairngorm-manifest.xmlには以下の内容が記述されていました。

<?xml version="1.0"?>
<componentPackage>
    <component id="ServiceLocator" class="com.adobe.cairngorm.business.ServiceLocator"/>
</componentPackage>
そのcairngorm-manifest.xmlは誰が見ているのかといいますと。。
.flexLibPropertiesの21行目でcairngorm-manifest.xmlをエントリしているようです。
<namespaceManifestEntry namespace="http://www.adobe.com/2006/cairngorm" manifest="cairngorm-manifest.xml"/>

じゃあいったい.flexLibPropertiesは誰が見てるのでしょうか??
残念ながらここから先はわかりませんでした↓↓
判明したらまたこのページを更新しておきます。無念。

さて、解決しました。たぶん。
↑のような事じゃなくって、ServiceLocatorって、Singletonなのですが、コンストラクタ内で、「instance = this;」って書いてます。
従って、
ApplicationMxmlで定義した、Service.mxmlが初期化されるときに、
暗黙的にsuper()が呼ばれるので、親クラスであるServiceLocatorのprivate static な自インスタンスにService.mxmlクラスのインスタンスが入っちゃうと。

Singleton破りなくラスでしたっ!

この模様は、FxUGのほうでも展開してましたので、そちらも。フォーラム - Flex User Group


次回は【ViewHelper】役割と実装例です。