Seasar DI Container with AOP

DIContainerExerciseの解説

S2Containerの定義に関する問題の解説

問題1

【解説】
components21.dtdには、次の項目が追加されました。
<initMethod>タグの子タグに<meta>タグは指定できません。

・<component>タグのinstance属性にrequestを追加
- 指定することでリクエスト毎に1つのインスタンスを作成します。

・<component>タグのinstance属性にsessionを追加
- 指定することでセッション毎に1つのインスタンスを作成します。

・<components>、<component>、<arg>、<property>タグの子タグに<meta>タグを追加
- 指定することで各タグに対応した定義クラスにメタデータを保持させることが可能になります。

<< 問題へ戻る
次の問題へ>>

S2Containerの生成に関する問題の解説

問題1

【解説】
S2Containerを生成する場合は以下のメソッドを使用します。
- org.seasar.framework.container.factory.S2ContainerFactory#create(String path)

1,2,3はS2ContainerFactoryに存在しないメソッドなので間違いです。

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
S2ContainerFactory#create(String path)の引数はCLASSPATHで指定されているディレクトリを ルートとする設定ファイルの絶対パスです。

2は絶対パスを指定してないので間違いです。
3は絶対パスの前に"/"が入っているので間違いです。
4はファイルの拡張子(dicon)がないため間違いです。

<< 問題へ戻る
次の問題へ>>

コンポーネントの取得に関する問題の解説

問題1

【解説】
S2Containerからコンポーネントを取り出すには以下のメソッドを使用します。
-org.seasar.framework.container.S2Container#getComponent(Object componentKey)
componentKeyにはコンポーネント名または、コンポーネントのクラスを指定します。

1は指定したキーに対応するコンポーネント定義を取得するメソッドなので間違いです。
2,4はS2Containerに存在しないメソッドなので間違いです。

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
S2Container#getComponent(Object componentKey)の引数にコンポーネント名を指定するとS2Containerに登録されているコンポーネントを取得することができます。

1はコンポーネント名は大文字小文字を区別するので間違いです。
2,4はコンポーネント名を指定してないので間違いです。

<< 問題へ戻る
次の問題へ>>

問題3

【解説】
S2Container#getComponent(Object componentKey)の引数にクラス名を指定するとコンポーネントを取得することができます。

1,3は引数が文字列なのでコンポーネントとして扱われてしまうので、間違いです。
4は".class"が抜けているので間違いです。

<< 問題へ戻る
次の問題へ>>

問題4

【解説】
コンポーネントが見つからなかったときは、以下の例外が発生します。
- org.seasar.framework.container.ComponentNotFoundRuntimeException

発生した場合のメッセージは次のようになります。{0}にはコンポーネント名が入ります。
[ESSR0046]コンポーネント({0})が見つかりません

1,3はクラス名を指定し、コンポーネントを取得できるので間違いです。
2はコンポーネント名を指定し、コンポーネントを取得できるので間違いです。

<< 問題へ戻る
次の問題へ>>

問題5

【解説】
同じコンポーネントが複数登録されていた場合、コンポーネントを取得しようとすると以下の例外が発生します。
- org.seasar.framework.container.TooManyRegistrationRuntimeException

発生した場合のメッセージは次のようになります。
{0}には定義されたインターフェースの完全限定名、 {1}にはコンポーネントクラスの完全限定名が入ります。
[ESSR0045]{0}に複数のコンポーネント({1})が登録されています

また、コンポーネント毎にname属性が一意になるように定義すると コンポーネントを識別できるのでこの例外を回避することができます。

2,3は存在しない例外なので間違いです。
4は定義されたコンポーネントのクラスと実際のコンポーネントのクラスが異なるときの実行時例外なので間違いです。

<< 問題へ戻る
次の問題へ>>

問題6

【解説】
CyclicReferenceRuntimeExceptionは、コンポーネントの実装クラスまたは、実装クラスのインターフェースをコンストラクタの引数に設定し、コンストラクタインジェクションを行うときに発生するRuntimeExceptionです。
発生した場合のメッセージは次のようになります。{0}には実装クラスの完全限定名が入ります。
[ESSR0047]{0}で循環参照が発生しました

<components>
  <component name="a" class="aaa.bbb.Ccc"/>
    <arg>b</arg>
  </component>
  <component name="b" class="aaa.bbb.Ccc">
    <arg>a</arg>
  </component>
</components>

上記のようにaコンポーネントがbコンポーネントを参照し、bコンポーネントがaコンポーネントを参照するような場合でも循環参照は発生します。
なお、セッターメソッドの引数にコンポーネントの実装クラス、実装クラスのインターフェースを設定し、 セッターインジェクションを行った場合は循環参照は発生しません。

2はコンポーネントが見つからないときに発生する例外なので間違いです。
3は同じコンポーネントが複数登録されていた場合、コンポーネントを取得しようとすると発生する例外なので間違いです。
4は存在しない例外なので間違いです。

<< 問題へ戻る
次の問題へ>>

問題7

【解説】
IllegalMethodRuntimeExceptionは、コンポーネントのメソッドの引数の設定に失敗した場合に発生するRuntimeExceptionです。 発生した場合のメッセージは次のようになります。{0}にはコンポーネントのクラス名、{1}にはメソッド名、{2}にはIllegalMethodRuntimeExceptionにマッピングされたExceptionの詳細が入ります。
[ESSR0060]クラス({0])のメソッド({1})の設定に失敗しました。理由は{2}

1はセッターインジェクションに変更してもエラーは発生するので間違いです。
なお、変更した場合は、org.seasar.framework.beans.IllegalPropertyRuntimeExceptionが発生します。
3はdiconファイルを修正することで正しく実行されるので間違いです。
4はエラーは発生するので間違いです。

<< 問題へ戻る
次の問題へ>>

問題8

【解説】
ContainerNotRegisteredRuntimeExceptionは、コンテナが見つからない場合に発生するRuntimeExceptionです。
発生した場合のメッセージは次のようになります。{0}には、指定したパス名が入ります。
[ESSR0075]({0})のコンテナはまだ登録されていません

2はS2Containerもコンポーネント登録されていますが、この場合は発生しないので間違いです。
3は存在しないRuntimeExceptionなので間違いです。
4はnullを返すことはないので間違いです。

<< 問題へ戻る
次の問題へ>>

問題9

【解説】
ExtensionNotFoundRuntimeExceptionは、パスを指定する際に拡張子を指定しない場合に発生するRuntimeExceptionです。
発生した場合のメッセージは次のようになります。{0}には、指定したパス名が入ります。
[ESSR0074]{0}に拡張子が見つかりません

1は正しくS2Containerが生成されるので間違いです。
2は違う拡張子を指定した場合は、org.seasar.framework.util.ResourceNotFoundRuntimeExceptionが発生するので間違いです。
4はフルパスを指定せずにファイル名のみ指定した場合は、org.seasar.framework.util.ResourceNotFoundRuntimeExceptionが発生するので間違いです。

<< 問題へ戻る
次の問題へ>>

コンストラクタ・インジェクションに関する問題の解説

問題1

【解説】
コンストラクタ・インジェクションでコンストラクタの引数に値を設定する場合は、 <component>タグの子タグに<arg>タグを使用します。
S2Containerに他のコンポーネントが登録されている場合は、<arg>コンポーネント名</arg>でも設定することができます。

2は文字列はダブルクォーテーション(")が必要なので間違いです。
3は<component>タグの子タグに<args>タグはないので間違いです。
4は2,3と同じなので間違いです。

<< 問題へ戻る
次の問題へ>>

セッター・インジェクションに関する問題の解説

問題1

【解説】
セッター・インジェクションでセッター・メソッドに値を設定する場合は、<property>タグを 使用し、name属性でプロパティ名を指定する必要があります。

1は<property>タグのname属性が記述されていないので間違いです。
3は<arg>タグにname属性はないので間違いです。
4はS2Containerの定義タグに<message>タグはないので間違いです。

<< 問題へ戻る
次の問題へ>>

メソッド・インジェクションに関する問題の解説

問題1

【解説】
メソッド・インジェクションを用いて、任意のメソッドに値を設定する場合は以下のように記述し、 <initMethod>タグのname属性でメソッド名を指定します。

<initMethod name="メソッド名">
  <arg>
    ...
  </arg>
</initMethod>

また、name属性を省略して、ボディで、OGNL式を使うこともできます。
その場合、<arg>タグは必要ありません。#selfはコンポーネント自身を表します。
この問題の答えを#selfを使ったものに書き直すと以下のようになります。

<initMethod>
  #self.setTime(0)
</initMethod>

1は<property>タグはセッター・インジェクションで使用するので間違いです。
2は<arg>タグはコンストラクタ・インジェクションで使用するので間違いです。
3は<arg>タグが記述されてないので間違いです。

<< 問題へ戻る
次の問題へ>>

自動バインディングに関する問題の解説

問題1

【解説】
<component>タグのautoBinding属性を省略した場合、autoBinding属性にはautoが設定されます。

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
自動バインディングをできないように設定するには、<component>タグのautoBinding属性にnoneを指定します。

1,3,4は自動バインディングできるので間違いです。

<< 問題へ戻る
次の問題へ>>

問題3

【解説】
自動バインディングするには、<component>タグのautoBinding属性を指定します。
autoBinding属性を省略するとautoが自動的に設定されます。

2はautoBinding属性にnoneを指定すると、自動バインディングできないので間違いです。
3は型がインターフェースのプロパティを自動的にバインドしたいときに指定するので間違いです。
4は<component>タグのautoBinding属性にMessageImplというのはないので間違いです。

<< 問題へ戻る
次の問題へ>>

問題4

【解説】
デフォルトのコンストラクタがない場合、コンストラクタに自動バインディングするには、 コンストラクタの引数の値が全てインタフェースである必要があります。

1,3,4は実装クラスまたは抽象クラスなので間違いです。

<< 問題へ戻る
次の問題へ>>

問題5

【解説】
引数のないデフォルトコンストラクタが定義されている場合は デフォルトのコンストラクタが使用されます。

1,2はデフォルトコンストラクタが定義されているので間違いです。
4はデフォルトのコンストラクタが呼ばれるので間違いです。

<< 問題へ戻る
次の問題へ>>

問題6

【解説】
デフォルトのコンストラクタがない場合、コンストラクタの引数の数が1以上で、引数の型がすべてインターフェースの コンストラクタで最も引数の数が多いものを使います。

1は定義されているコンストラクタの中で一番引数の数が少ないので間違いです。
2はコンストラクタの引数の中にインターフェースでないものが混ざっているので間違いです。
3はprivateで不可視になっているので間違いです。

<< 問題へ戻る
次の問題へ>>

問題7

【解説】
セッターメソッドはset〜という名前になります。

1,2,4はセッターメソッドの名前がsetから始まり、自動バインディングされるので間違いです。

<< 問題へ戻る
次の問題へ>>

問題8

【解説】
引数がインターフェースのセッターメソッドに自動バインディングします。 この場合、ArrayListがdiconファイルに定義されているので、引数がListのセッターメソッドが呼ばれます。

1はセッターメソッドのsetのsが大文字になっているので間違いです。
2,3はセッターメソッドの引数がインターフェースではないので間違いです。

<< 問題へ戻る
次の問題へ>>

問題9

【解説】
引数が一つのセッターメソッドが呼ばれます。

<< 問題へ戻る
次の問題へ>>

問題10

【解説】
<component>タグのautoBinding属性に"auto"を指定するとコンストラクタとセッターメソッドに自動バインディングすることができます。 また、autoBinding属性に"constructor"を指定するとコンストラクタにのみ自動バインディングされ、"property"を指定するとセッターメソッドに自動バインディングされます。

<< 問題へ戻る
次の問題へ>>

S2Container定義の分割とインクルードに関する問題の解説

問題1

【解説】
コンポーネントの検索は、まず、自分自身のコンポーネントを検索し、 次にincludeされているコンポーネントを登録している順に検索します。 最初にコンポーネントが見つかった時点でそのコンポーネントを返します。

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
S2Containerはインクルード先のコンポーネントを自動インジェクションすることができ、 <include>タグで先に登録したほうのコンポーネントの値が設定されます。

<< 問題へ戻る
次の問題へ>>

問題3

【解説】
直接コンポーネント名がbbbというコンポーネントを取得しているので、そのままbbbのコンポーネントにセットされている "Hello Bbb!"が表示されます。

<< 問題へ戻る
次の問題へ>>

名前空間に関する問題の解説

問題1

【解説】
他のS2Container定義のコンポーネントを参照する場合は、 名前空間をコンポーネント名の頭につけます。

1,3はroot.diconに定義されているコンポーネント名がbbbのコンポーネントを参照するので間違いです。
4は文字列"child.bbb"がセットされるので間違いです。

<< 問題へ戻る
次の問題へ>>

インスタンス管理に関する問題の解説

問題1

【解説】
<component>タグのinstance属性を省略した場合、singletonが設定されます。

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
<component>タグのinstance属性を省略すると、singletonがデフォルトで設定されるため、そのコンポーネントはシングルトンになり、同じインスタンスを返します。

1,3,4はMessageMainクラスで、messageプロパティを"Hello World!"に変更しているので間違いです。

<< 問題へ戻る
次の問題へ>>

問題3

【解説】
セッション毎に1つのインスタンスを作成したい場合、instance属性にsessionを指定します。 また、name属性に指定した名前で、コンポーネントがセッションに格納されます。

1はS2Container#getComponent()を何度呼び出しても同じインスタンスを返したい場合に指定するので間違いです。
3はS2Container#getComponent()を呼び出すたびに、新たに作成されたコンポーネントを返して欲しい場合に指定するので間違いです。
4は<component>タグのinstance属性に存在しないので間違いです。

<< 問題へ戻る
次の問題へ>>

問題4

【解説】
<component>タグのinstance属性にrequestを指定すると、リクエスト毎に1つのインスタンスが作成されます。 また、name属性に指定した名前で、コンポーネントがリクエストに格納されます。

1はセッション毎に1つのインスタンスを作成したい場合に指定するので間違いです。
3,4は<component>タグのinstance属性に存在しないので間違いです。

<< 問題へ戻る
次の問題へ>>

問題5

【解説】
S2Container外のコンポーネントに対してDependency Injectionする場合、以下のメソッドを使用します。

- org.seasar.framework.container.S2Container#injectDependency(Object outerComponent)
- org.seasar.framework.container.S2Container#injectDependency(Object outerComponent, Class componentClass)
- org.seasar.framework.container.S2Container#injectDependency(Object outerComponent, String componentName)

2はクラスをコンポーネント定義として登録するメソッドなので間違いです。
3はS2Container#getComponent()はコンポーネントを取得するメソッドなので間違いです。
4はS2Containerに存在しないメソッドなので間違いです。

<< 問題へ戻る
次の問題へ>>

問題6

【解説】
S2Container外のコンポーネントに対してDependency Injectionする場合、コンポーネント名だけでなく コンポーネントクラス名でも指定することができます。

2,3,4はHashMapの値が設定されるので間違いです。

<< 問題へ戻る
次の問題へ>>

問題7

【解説】
ClassUnmatchRuntimeExceptionは、異なるクラスを使用してDependencyInjectionを行った場合に発生するRuntimeExceptionです。 発生した場合のメッセージは次のようになります。{0}には定義されたクラスの完全限定名、{1}には実際のクラスの完全限定名が入ります。
[ESSR0069]定義されたクラス({0})に実際のクラス({1])を適用できません

2はコンポーネントが見つからない場合に発生するRuntimeExceptionなので間違いです。
ただし、injectDependency(hashMap)のようにコンポーネント名を省略した場合は、ComponentNotFoundRuntimeExceptionが発生します。
3は存在しないRuntimeExceptionなので間違いです。
4は発生するので間違いです。

<< 問題へ戻る
次の問題へ>>

ライフサイクルに関する問題の解説

問題1

【解説】
S2Container終了時に<destroyMethod>タグで指定したメソッドが呼び出されます。

2は引数の設定が逆になっているので間違いです。
3は初期化処理を設定する<initMethod>タグなので間違いです。
4はメソッド名が"get"になっているので間違いです。

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
<initMethod>タグはコンポーネントがコンテナに登録した順番に実行され、 <destroyMethod>タグはその逆順に呼び出されます。

1は終了処理は登録した順番の逆順になるので間違いです。
3はlistコンポーネントに<destroyMethod>タグが定義され、終了処理は行われるので間違いです。
4は<component>タグのinstance属性が"singleton"の場合、終了処理は行われるので間違いです。

<< 問題へ戻る
次の問題へ>>

問題3

【解説】
<component>タグのinstance属性がsingleton以外の場合、destroyMethodを指定しても無視されます。

<< 問題へ戻る
次の問題へ>>

コンポーネントでS2Containerを利用するに関する問題の解説

問題1

【解説】
S2Containerはcontainerという名前で登録されています。

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
S2Containerはcontainerと言う名前で登録されているので、自動インジェクションする場合は書く必要はありません。

<< 問題へ戻る
次の問題へ>>

S2ContainerServletに関する問題の解説

問題1

【解説】
SingletonS2ContainerFactory#initで生成したS2Containerを取得するにはSingletonS2ContainerFactory#getContainer()を使用します。

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
S2ContainerServletは、他のサーブレットよりもはやく開始されるように、web.xmlのタグを調整します。

<< 問題へ戻る
次の問題へ>>

問題3

【解説】
S2Containerのライフサイクルは、S2ContainerServletと連動するため、web.xmlに記述したdebugパラメータをtrueにして以下のURLにアクセスすると稼動中にS2Containerを再起動することできます。
http://localhost:8080/xxx/s2servlet?command=restart

<< 問題へ戻る
次の問題へ>>

app.diconの役割に関する問題の解説

問題1

【解説】
すべてのS2Container定義のルートになる定義ファイルは、慣例でapp.diconという名前にします。 app.diconにはincludeの定義を記述し、コンポーネントの定義はしないようにしてください。 また、app.diconは通常WEB-INF/classes以下に配置します。

<< 問題へ戻る
次の問題へ>>

メタデータに関する問題の解説

問題1

【解説】
<components>、<component>、<arg>、<property>タグにメタデータを指定することができます。 定義したメタデータの情報はS2Container、ComponentDef、ArgDef、PropertyDefで定義されている 以下のメソッドで取得することが出来ます。

・public int getMetaDefSize()
・public MetaDef getMetaDef(int index)
・public MetaDef getMetaDef(String name)
・public MetaDef[] getMetaDefs(String name)

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
<meta>タグの値をS2Container#getMetaDef()で取得する場合、<meta>タグのname属性を引数に指定することで取得することができます。

<< 問題へ戻る
次の問題へ>>

問題3

【解説】
S2Container#getmetaDefs(String name)を用いると配列でメタデータの値を取得することができます。 <meta>タグのname属性に複数同じ名前がある場合、S2Container#getmetaDefs(String name)の引数に その名前を指定すると、その名前で定義されているメタデータをすべて配列に格納することができます。

<< 問題へ戻る
次の問題へ>>

OGNL式に関する問題の解説

問題1

【解説】
diconファイルで文字列をセットする場合は、"hoge"のように"で囲みます。

<< 問題へ戻る
次の問題へ>>

問題2

【解説】
diconファイルでcharは、'a'のように'で囲みます。

<< 問題へ戻る
次の問題へ>>

問題3

【解説】
diconファイルで論理値は、true,falseのようにそのまま記述します。

<< 問題へ戻る
次の問題へ>>

問題4

【解説】
new java.lang.String("foo")のようにクラスの完全限定名で指定してもコンストラクタを呼び出すことができます。

<< 問題へ戻る
次の問題へ>>

問題5

【解説】
@java.lang.Math@max(1, 2)のようにしてstaticなメソッドの呼び出した結果を参照することができます。

<< 問題へ戻る
次の問題へ>>

問題6

【解説】
OGNL式は文字列で記述した内容(式)をJavaのオブジェクトに変換するためのものです。

1はクラスを参照するときの正しい記述なので間違いです。
2は数値の設定の正しい記述なので間違いです。
4は文字列の設定の正しい記述なので間違いです。

<< 問題へ戻る
次の問題へ>>

問題7

【解説】
foo.getMessage()のようにコンポーネントのメソッドを呼び出した結果を参照することができます。

<< 問題へ戻る
次の問題へ>>

問題8

【解説】
#selfは自分自身のコンポーネントを表します。 使い方は以下のようになります。

#self.メソッド名(引数1、引数2、引数3...)

<< 問題へ戻る
次の問題へ>>

問題9

【解説】
#outはSystem.outを表します。

2は#outだけではコンソールに出力できないので間違いです。
3,4はognl式で存在しないので間違いです。

<< 問題へ戻る
次の問題へ>>

問題10

【解説】
#errはSystem.errを表します。

1は#errだけではエラーメッセージを出力できないので間違いです。
3,4はognl式で存在しないので間違いです。

<< 問題へ戻る
次の問題へ>>

問題11

【解説】
#self,#out,#errは<initMethod>タグ内で有効なオブジェクトです。

4は#systemはognl式で存在しないので間違いです。

<< 問題へ戻る