コンポーネント定義
はじめに 本章では,diconファイルでコンポーネントを定義する方法について説明します.
コンポーネント コンポーネントとは,S2コンテナに管理されるオブジェクトのことです. S2コンテナで管理可能なコンポーネントは特別なクラスである必要はなく,ほとんどのJavaクラスをコンポーネントとして扱うことが可能です.
<literal><component></literal>要素 -コンポーネント定義- コンポーネントは<component>要素で定義します. <component name="componentName" class="fullQualifiedClassName" instance="singleton | prototype | outer | request | session | application" autoBinding="auto | constructor | property | semiauto | none" externalBinding="true | false" > ... </component> name (任意): コンポーネントの名前を指定します. class (任意): コンポーネントのクラス名 (完全限定名) を指定します. instance (任意): インスタンス・モードを指定します. デフォルトはsingletonです. autoBinding (任意): 自動バインディング・モードを指定します.デフォルトはautoです. externalBinding (任意): 外部バインディング・モードを指定します. デフォルトはfalseです. <component>要素の内容には,次のものを記述することができます. インスタンス生成式 <arg>要素 <property>要素 <initMethod>要素 <destroyMethod>要素 <aspect>要素 <interType>要素 (Seasar2.4以降) <meta>要素 (Seasar2.1以降) <description>要素 <component>要素は,次の要素の子として記述することができます. <components>要素 <arg>要素 <property>要素 <aspect>要素 <interType>要素 (Seasar2.4以降) <meta>要素 (Seasar2.1以降) <components>要素以外の要素の子として定義したコンポーネントは,他のコンポーネントから参照することができません.
<literal>name</literal>属性 -コンポーネント名- コンポーネント名 name属性で指定するコンポーネント名は,<components>要素の直下に定義した<component>要素のみ有効です. コンポーネントは名前を持つことができます. この名前は,コンテナからコンポーネントを取得する際のキーとして使うことができます (). また,自動バインディグの際にはプロパティ名とのマッチングに使用されます (). インスタンス・モードがrequestsessionapplicationの場合,コンポーネント名は必須です. JavaBeansのプロパティ名 JavaBeansの仕様では,プロパティ名の最初の文字は小文字となります. ただし,二文字目が大文字の場合は先頭も大文字となります. 正: fooBar, z, URL 誤: FooBar, Z, url, uRL コンポーネント名は,Javaの識別子として有効な名前を指定します. JavaBeansのプロパティ名と同じルールに従うことを推奨します. コンポーネント名は,<components>要素の直下に定義されたコンポーネント定義の場合のみ有効です. <property>要素など,他の要素の子として定義された<component>要素では,name属性は無視されます.
<literal>class</literal>属性 -コンポーネント・クラス- ネステッド・クラスを指定する コンポーネント・クラスにネステッド・クラスを指定するには,外側のクラスとネステッド・クラスの区切りにピリオド (.)ではなく,ドル記号 ($) を使用します. foo.bar.Outer$Inner コンポーネントのクラスを指定することができます. この指定の必要性と解釈はinstance属性の値がouterかどうかと,インスタンス生成式の有無によって変わります. <literal>instance</literal>属性・インスタンス生成式と<literal>class</literal>属性の関係 instance属性 インスタンス生成式 class属性 説明 outer以外 あり あり インスタンス生成式によって生成されるインスタンスがコンポーネントとなります. このインスタンスは,class属性で指定されたクラスに代入可能でなくてはなりません. 代入可能でない場合は,org.seasar.framework.container.ClassUnmatchRuntimeExceptionがスローされます. なし インスタンス生成式によって生成されるインスタンスがコンポーネントとなります. なし あり 指定されたクラスのインスタンスがコンポーネントとなります. インスタンスの生成に使用されるコンストラクタについては,「コンストラクタ・インジェクション」を参照してください. なし エラー. インスタンス生成式またはclass属性のどちらかが必要です. 両方が省略されるとorg.seasar.framework.container.factory.TagAttributeNotDefinedRuntimeExceptionがスローされます. outer - あり 外部から渡されるインスタンスがコンポーネントとなります. class属性が指定された場合,外部から渡されるインスタンスはclass属性で指定されたクラスに代入可能でなくてはなりません. 代入可能でない場合は,org.seasar.framework.container.ClassUnmatchRuntimeExceptionがスローされます. なし 外部から渡されるインスタンスがコンポーネントとなります.
<literal>instance</literal>属性 -インスタンス・モード- インスタンス・モードとして,コンポーネントのスコープを指定することができます. 指定可能な値を次に示します. singleton (デフォルト) コンテナ内で唯一のインスタンスが作成されるモードです. singletonのインスタンスはコンテナの初期化時に作成されます. コンテナからコンポーネントが取得されると,毎回同一のインスタンスが返されます. prototype コンテナからコンポーネントが取得される度に,新しいインスタンスが作成されるモードです. outer 外部で作成されたインスタンスがコンテナに渡されるモードです. コンテナはouterのコンポーネントについてはインスタンスの生成も管理も行いません. outerは,コンテナの外部で生成されたインスタンスにDIを適用するためのモードです. request (Version: 2.1~) リクエスト単位にインスタンスが作成されるモードです. requestモードでは,name属性が必須となります. requestモードを使用するにはコンテナに外部コンテキストが設定されている必要があります.外部コンテキストの詳細は「」を参照してください. Webアプリケーションでは,requestのインスタンスはHttpServletRequestの属性として保持されます. コンポーネントが取得される際,コンテナはHttpServletRequestからコンポーネント名をキーとして属性を取得します. 属性が存在しなければ,コンポーネントをインスタンス化してHttpServletRequestに設定し,それをコンポーネントとして返します. 属性が存在すれば,それをコンポーネントとして返します (). session (Version: 2.1~) セッション単位にインスタンスが作成されるモードです. sessionモードでは,name属性が必須となります. sessionモードを使用するにはコンテナに外部コンテキストが設定されている必要があります.外部コンテキストの詳細は「」を参照してください. Webアプリケーションでは,sessionのインスタンスはHttpSessionの属性として保持されます. コンポーネントが取得される際,コンテナはHttpSessiontからコンポーネント名をキーとして属性を取得します. 属性が存在しなければ,コンポーネントをインスタンス化してHttpSessionに設定し,それをコンポーネントとして返します. 属性が存在すれば,それをコンポーネントとして返します (). application (Version: 2.4~) アプリケーション単位にインスタンスが作成されるモードです. applicationモードでは,name属性が必須となります. applicationモードを使用するにはコンテナに外部コンテキストが設定されている必要があります.外部コンテキストの詳細は「」を参照してください. Webアプリケーションでは,applicationのインスタンスはServletContextの属性として保持されます. コンポーネントが取得される際,コンテナはServletContextからコンポーネント名をキーとして属性を取得します. 属性が存在しなければ,コンポーネントをインスタンス化してServletContextに設定し,それをコンポーネントとして返します. 属性が存在すれば,それをコンポーネントとして返します.
<literal>autoBinding</literal>属性 -自動バインディング・モード- 自動バインディングのモードを指定することができます. 自動バインディングの詳細は「」を参照してください. autoBinding属性に指定可能な値を次に示します. auto (デフォルト) コンストラクタ・インジェクションとセッター・インジェクションの両方に自動バインディングが適用されます. constructor コンストラクタ・インジェクションに対してのみ,自動バインディングが適用されます. property セッター・インジェクションに対してのみ,自動バインディングが適用されます. none 自動バインディングは適用されません. semiauto (Seasar2.4以降) アノテーション等で明示的に指定されたプロパティに対してのみ,自動バインディングが適用されます.
(Version: 2.4.0~) <literal>externalBinding</literal>属性 -外部バインディング・モード- 外部バインディングを使用するかどうかを指定することができます. 外部バインディングの詳細は「」を参照してください. externalBinding属性に指定可能な値を次に示します. false (デフォルト) 外部バインディングを使用しません. true 外部バインディングを使用します.
インスタンス生成式 コンストラクタを使用してインスタンスを生成する場合は「コンストラクタ・インジェクション」を参照してください. <component>要素の内容に,コンポーネントのインスタンスを生成するためのOGNL式を記述することができます. OGNL式の詳細は「」を参照してください. OGNL式を評価した結果のオブジェクトがコンポーネントのインスタンスとなります. <component name="hoge"> new foo.bar.Hoge() </component> インスタンス生成式を使うことにより,シングルトン・パターンやファクトリによって取得したインスタンスや定数をコンポーネントとして扱うことができます. <component name="hoge"> @foo.bar.HogeFactory@getInstance() </component> インスタンス生成式は,コンポーネントが作成される際に評価されます. <component>要素にclass属性が指定された場合は,インスタンス生成式を評価した結果のオブジェクトはclass属性で指定されたクラスに代入可能でなくてはなりません. 代入可能でない場合は,org.seasar.framework.container.ClassUnmatchRuntimeExceptionがスローされます.
まとめ