3.2. S2ApplicationContext リファレンス

S2ApplicationContextの主な機能は次になります。

S2ApplicationContextを用いてS2Containerを生成する場合は、ダイコンファイルによるコンポーネント定義は必要としません。 ファイルシステムからクラスを検索する際に、ダイコンファイル(.dicon)が見つかった場合は、インクルード対象として自動的に読み込みます。 頻繁に使用するコンポーネントのセットを設定ファイルとしてダイコンファイルを用いることができます。


3.2.1. コンポーネントのインポート

クラスのインポートは次のメソッドで行います。

S2ApplicationContext::import($path, $namespace = array(), $strict = false, $pear = false, $recursive = true)
  • 第1引数 : 検索するディレクトリへのパス
  • 第2引数 : namespaceの文字列または配列
  • 第3引数 : trueの場合、$namespaceで指定されたネームスペースが使用されます。falseの場合は、検索したサブディレクトリが$namespaceに順次追加されます。
  • 第4引数 : trueの場合は、$namespaceが「_」で展開されます。falseの場合は、$namespaceが「\」で展開されます
  • 第5引数 : trueの場合は、再帰的にディレクトリを検索します。falseの場合は、サブディレクトリを検索しません。

 第1引数で指定したディレクトリにあるクラスファイル( .php、.class.php など)、ダイコンファイル( .dicon )をインポートします。 インポートではクラス名とクラスファイルのパスを取得します。この情報はautoload関数でクラス定義がrequireされる際に使用されます。 クラス名はクラスファイル名の拡張子を除く部分になります。クラスファイル名がS2Container.phpやS2Container.class.phpの場合、 「S2Container」がクラス名になります。 S2ApplicationContext::importメソッドへのショートカットとして、s2import関数も定義されています。


3.2.2. S2Containerの生成

S2Containerインスタンスの生成は次のメソッドで行います。

S2ApplicationContext::create($namespaces = array())

生成されるS2Containerは、importメソッドでインポートされた全クラスをコンポーネントとして持ちます。 importメソッドが実行されていない場合は、コンポーネントを持たない空のS2Containerインスタンスが戻ります。 importメソッドで取得されたダイコンファイルについては、そのダイコンファイルを用いてS2Containerを生成し、子コンテナとしてincludeします。

namespace引数を設定した場合は、指定されたnamespaceに含まれるコンポーネントを持つS2Containerインスタンスが返されます。 例として、グローバル(namespace指定無し)にFooクラスがあり、example namespaceにBarクラスが ある場合は、次のようにS2Containerを生成できます。

Fooクラスを /path/to/classes/Foo.php に作成します。

<?php
/**
 * @S2Component('name' => 'foo')
 */
class Foo {}

Barクラスを /path/to/classes/Bar.php に作成します。

<?php
/**
 * @S2Component('name' => 'bar', 'namespace' => 'example')
 */
class Bar {}

実行スクリプトは次になります。

<?php
require_once('S2Container/S2Container.php');
seasar\container\S2ApplicationContext::import('/path/to/classes');

// グローバルコンテナの生成
$globalContainer = seasar\container\S2ApplicationContext::create();
$foo = $globalContainer->getComponent('Foo');
$bar = $globalContainer->getComponent('example.Bar');

// example namespace コンテナの生成
$exampleContainer = seasar\container\S2ApplicationContext::create('example');
$foo = $exampleContainer->getComponent('Foo');          // コンポーネントが存在しないので例外がスローされます。
$bar = $exampleContainer->getComponent('Bar');
[注意]注意

S2Container内で子コンテナを管理する ”namespace” と、PHPの ”namespace” には関連はありません。


3.2.3. コンポーネントの選択

createメソッドでS2Containerを生成する際に、インポートされたクラスやダイコンファイルから一部を選択することができます。

  • default (パターン設定無し) : インポートされた全てのクラスをコンポーネントとして扱い、全てのダイコンファイルを子コンテナとしてincludeします。
  • Include Pattern : インポートされたクラスファイルとダイコンファイルに対してパターンにマッチ( preg_match )するもののみを使用します。
  • Exclude Pattern : インポートされたクラスファイルとダイコンファイルに対してパターンにマッチ( preg_match )するものは除外します。
  • Include & Exclude : Include PatternとExclude Patternが両方設定されている場合は、Include PatternにマッチしたものからExclude Patternにマッチしたものが除外されます。

setIncludePattern メソッド. 

S2ApplicationContext::setIncludePattern($pattern)
  • 第1引数 : 正規表現文字列
引数の正規表現はpreg_match関数で使用されます。クラス名が「 Bean 」で終わっているクラスを含めたい場合は、引数値は「 /Bean$/ 」となります。  setIncludePatternメソッドは、現在設定されているInclude Patternを上書きします。


addIncludePatternメソッド. 

S2ApplicationContext::addIncludePattern($pattern)
  • 第1引数 : 正規表現文字列
 addIncludePatternメソッドは、現在設定されているInclude Patternにパターンを追加します。


setExcludePatternメソッド. 

S2ApplicationContext::setExcludePattern($pattern)
  • 第1引数 : 正規表現文字列
引数の正規表現はpreg_match関数で使用されます。クラス名が「 Abstract 」を含むクラスを除外する場合は、引数値は「 /Abstract/ 」となります。 setExcludePatternメソッドは、現在設定されているExclude Patternを上書きします。


addExcludePatternメソッド. 

S2ApplicationContext::addEcludePattern($pattern)
  • 第1引数 : 正規表現文字列
addExcludePatternメソッドは、現在設定されているExclude Patternにパターンを追加します。


3.2.4. コンポーネントの手動登録

コンポーネントを手動で登録します。

S2ApplicationContext::register($info)
  • 第1引数 : クラス名 | ReflectionClass | ComponentInfoDefインスタンス
  • 戻り値 : ComponentInfoDefインスタンス

Serviceクラスを手動でコンポーネント登録する場合は次のようになります。

S2ApplicationContext::register('Service');

S2ApplicationContext::registerメソッドへのショートカットとして、s2component関数が定義されています。使用方法はregisterメソッドと同じです。

s2component('Service');

戻り値のComponentInfoDefインスタンスを使用して、コンポーネント設定を追加できます。

s2component('Service')
  ->setName('indexService')
  ->setInstance('singleton')
  ->setAutoBinding('auto')
  ->setNamespace('example')
  ->setConstructClosure(function(){return new Service;});
[注意]注意

コンポーネントの手動登録では、アノテーションによる設定は反映されません。また、autoloadも実施されません。


3.2.5. 自動アスペクト

コンポーネントの選択でインクルードされたコンポーネントに対して、自動的にアスペクトを適用します。

S2ApplicationContext::registerAspect($interceptor, $componentPattern = null, $pointcut = null)
  • 第1引数 : Interceptorコンポーネント名、Closure、またはExpression
  • 第2引数 : コンポーネント名またはコンポーネントクラス名にパターンマッチする正規表現文字列
  • 第3引数 : ポイントカットを正規表現文字列で指定
  • 戻り値 : AspectInfoDefインスタンス

コンポーネントクラス名が「Dao」で終わっているコンポーネントに、dao.interceptorをアスペクトしたい場合は次のように設定します。

S2ApplicationContext::registerAspect('dao.interceptor', '/Dao$/');

S2ApplicationContext::registerAspectメソッドへのショートカットとして、s2aspect関数が定義されています。使用方法はregisterAspectメソッドと同じです。

s2aspect('dao.interceptor', '/Dao$/');

戻り値のAspectInfoDefを使用して、aspect設定を追加することもできます。

s2aspect('dao.interceptor')
  ->setPattern('/Dao$/')
  ->setPointcut('/^find/');

次の例では、Closureをインターセプターとして設定しています。Closureの第1引数にはMethodInvocationインスタンスが渡されます。

s2aspect()
  ->setPattern('/Service$/')
  ->setPointcut('/^add/')
  ->setInterceptor(function($invoker) {
        return $invoker->proceed() * 1.05;
    });
[注意]注意

自動アスペクトはimportされたコンポーネントに対してのみ適用されます。importされたダイコンファイルに含まれるコンポーネントには適用されません。


3.2.6. アノテーション

コンポーネントの細かい設定や、Dependency Injection設定、Aspectの適用を行う場合はアノテーションを用います。 アノテーションの形式は、@アノテーション名[()] です。アットマーク(@)で開始します。末尾はスペース、または改行となります。 アノテーションでは引数を記述することができます。引数の形式は、PHP配列と同じフォーマットです。


親クラスのメソッドアノテーション. 

デフォルトでは親クラスのメソッドアノテーションは無効となります。親クラスのメソッドアノテーションを有効とする場合は次のメソッドで設定します。

S2ApplicationContext::setReadParentAnnotation($val = true)
  • 第1引数 : bool値、trueを設定すると親クラスのメソッドアノテーションが有効となります。

@S2Component アノテーション. 

コンポーネント情報を設定します。

  • アノテーションの表記 : @S2Component
  • 引数
  • 注釈ポイント : クラス
  • サンプル
      /**
       * @S2Component('name' => 'hoge')
       */
      class Hoge{} 
      
      /**
       * @S2Component('name'        => 'huga',
       *              'instance'    => 'singleton',
       *              'autoBinding' => 'auto',
       *              'available'   => true,
       *              'namespace'   => 'example.service')
       */
      class Huga{} 
    

@S2Binding アノテーション. 

手動インジェクション設定を行います。

  • アノテーションの表記 : @S2Binding
  • 引数 : インジェクションするコンポーネント名、またはExpression
  • 注釈ポイント : pulbicプロパティ、セッターメソッド
  • サンプル
    class IndexAction {
        /**
         * @S2Binding('new HogeService')
         */
        public $service;
     
        /**
         * @S2Binding('Hello World')
         */
        public funcion setHello($val) {
            $this->hello = $val;
        }
    }
    

@S2Aspect アノテーション. 

アスペクト情報を設定します。

  • アノテーションの表記 : @S2Aspect
  • 引数
    • interceptor : Interceptorコンポーネント名、またはExpression
    • pointcut : ポイントカットを正規表現文字列で指定
  • 注釈ポイント : クラス、メソッド
  • サンプル
      /**
       * @S2Aspect('interceptor' => 'traceInterceptor',
       *           'pointcut'    => '/.+Action/')
       */
      class CdController {
          public function indexAction(){
              ・・・
          }
      }
    
      class DvdController {
          /**
           * @S2Aspect('interceptor' => 'new seasar\aop\interceptor\TraceInterceptor()')
           */
          public funcion indexAction() {
              ・・・
          }
      }
    

@S2Meta アノテーション. 

メタ情報を設定します。

  • アノテーションの表記 : @S2Meta
  • 引数
    • name : メタ情報の識別名
    • value : 値、またはExpression
  • 注釈ポイント : クラス
  • サンプル
      /**
       * @S2Meta('nameA' => 'valueA',
       *         'nameB' => 'valueB')
       */
      class CdController {
          public function indexAction(){
              ・・・
          }
      }
    

3.2.7. Singleton S2Container インスタンスの管理

S2ApplicationContextは、namespace単位でSingleton S2Containerを生成、管理します。 Singleton S2ContainerはS2ApplicationContext::$SINGLETON_CONTAINERSに保存されます。 Singleton S2Containerへのアクセスは次のメソッドで行います。

getメソッド (getComponentメソッド). 

S2ApplicationContext::get($key, $namespaces = array())
S2ApplicationContext::getComponent($key, $namespaces = array())
  • 第1引数 : コンポーネントのキー名
  • 第2引数 : S2Containerを管理するnamespace

getメソッドは getComponentメソッドのAliasです。 第1引数で指定されたコンポーネントを取得します。 第2引数で指定されたnamespaceのSingleton S2Containerが未作成の場合は、S2ApplicationContext::createメソッド を用いてコンテナを生成します。 S2ApplicationContext::getメソッドへのショートカットとして、s2get関数が定義されています。


getComponentDefメソッド. 

S2ApplicationContext::getComponentDef($key, $namespaces = array())
  • 第1引数 : コンポーネントのキー名
  • 第2引数 : S2Containerを管理するnamespace

第1引数で指定されたコンポーネント定義を取得します。 第2引数で指定されたnamespaceのSingleton S2Containerが未作成の場合は、S2ApplicationContext::createメソッド を用いてコンテナを生成します。

例として、グローバル(namespace指定無し)にFooクラスがあり、example namespaceにBarクラスが ある場合は、次のように 各コンポーネントを取得できます。

     

Fooクラスを /path/to/classes/Foo.php に作成します。

<?php
/**
 * @S2Component('name' => 'foo')
 */
class Foo {}

Barクラスを /path/to/classes/Bar.php に作成します。

<?php
/**
 * @S2Component('name' => 'bar', 'namespace' => 'example')
 */
class Bar {}

実行スクリプトは次になります。

<?php
require_once('S2Container/S2Container.php');
use seasar\container\S2ApplicationContext as s2app;
s2app::import('/path/to/classes');

// グローバルの Singleton コンテナを使用する
$globalFoo = s2app::get('Foo');
$globalBar = s2app::get('example.Bar');

// example namespace の Singleton コンテナを使用する
$exampleFoo = s2app::get('Foo', 'example');          // コンポーネントが存在しないので例外がスローされます。
$exampleBar = s2app::get('Bar', 'example');

var_dump($globalBar === $exampleBar);                // false となります。
[注意]注意

グローバルのSingletonコンテナが生成される際にexample namespaceのコンテナも生成され、子コンテナとして保持されていますが、 example namespaceのSingletonコンテナとは別インスタンスとなります。


3.2.8. S2ApplicationContextのInitialize

コンポーネントのインポート選択自動アスペクトなどで設定した情報、 また、getメソッドで生成されるSingleton S2Containerインスタンスは、 S2ApplicationContextのinitメソッドで初期化することができます。

S2ApplicationContext::init()

S2ApplicationContext::initメソッドへのショートカットとして、s2init関数も定義されています。




© Copyright The Seasar Foundation and the others 2005-2010, all rights reserved.