前書き
S2Containerを用いたソースコードを読んでいる時に、不明点があったのでメモ。
内容
登場人物
# インターフェース
aa.bb.cc.app.logic.SampleLogic;
# インターフェース実装クラス
aa.bb.cc.app.logic.impl.SampleLogicImpl
# 処理クラス
aa.bb.cc.app.logic.impl.MainLogicImpl
# コンポーネント定義ファイル
sample.dicon
※名前は適当に変えています。
本題
MainLogicImpl.java
@Binding
private SampleLogic sampleLogic = null;
(省略)
sampleLogic.do();
このように処理クラスで、フィールドにインターフェースを定義したあとそのままメソッドを呼び出していたので、DIされているとは思いつつSeaserに詳しくなかったのでとりあえず調べました。
定義は、sample.dicon
で行われていて、中身はこのようになってました。
sample.dicon
<component
class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
<property name="autoNaming">
<component
class="org.seasar.framework.container.autoregister.DefaultAutoNaming" />
</property>
<property name="instanceDef">
@org.seasar.framework.container.deployer.InstanceDefFactory@PROTOTYPE
</property>
<initMethod name="addClassPattern">
<arg>"aa.bb.cc.app.logic.impl"</arg>
<arg>".*Logic.*"</arg>
</initMethod>
</component>
ここでは、コンポーネントの自動登録の設定を記述しており、"aa.bb.cc.app.logic.impl"
にある".*Logic.*"
の正規表現を満たすファイルが登録されます。
ということなので登場人物であるaa.bb.cc.app.logic.impl.SampleLogicImpl
はコンポーネント登録の対象になります。
ここで今回重要になる仕様なのですが、
-
登録名は、登録されたコンポーネントのファイル名から、Implを除去した名前になります。
-
プロパティの型がインターフェースの場合、 コンテナをその型で検索し、見つかったコンポーネントが設定されます。
ここで先ほどの処理クラスをみてみると
MainLogicImpl.java
@Binding
private SampleLogic sampleLogic = null;
(省略)
sampleLogic.do();
プロパティの型であるSampleLogic
がインターフェースなので、コンテナからSampleLogicImpl
からImplが除去されたSampleLogic
で登録されているaa.bb.cc.app.logic.impl.SampleLogicImpl
が設定されるということですね。
認識が間違っていたら申し訳ないですが、いったんこれで納得しました。