かとじゅんの技術日誌

技術の話をするところ

DI初級編

引き続き、Seasar2のDIについてお勉強しましょう。

http://s2container.seasar.org/ja/DIContainer.html
http://s2container.seasar.org/ja/DIContainer.html#FirstStep

FirstStepを読めばすぐわかるのですが、簡単に補足したいと思います。

昨日のエントリを読んでおけば、Greetingのサンプルは理解しやすいと思います。
Greetingを呼び出すクラスGreetingClientもインターフェイスと実装クラスに分離されているのがわかると思います。そして、GreetingMainからGreetingClientImplを呼び出しています。

説明にもあるように、GreetingMain#mainでは何か仕様変更があるたびにソースコードの修正が必要になります。実際のアプリケーションではこのようなシーンはあちこちにあるのではないでしょうか?つまり、このようにコンポーネント間が密に結合していることでアプリケーションの構造は変更に弱い構造となっているといえます。

それを打開するために、何とかコンポーネント間の結合を疎にすることができないか?
DIコンテナにお世話になればいいのです。

まず、GreetingとGreetingClientをそれぞれ DIコンテナの管理下に置きます。
どうするかというと、diconファイルに記述するだけです。
GreetingMain2.diconをご覧ください。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC    "-//SEASAR//DTD S2Container 2.3//EN"    "http://www.seasar.org/dtd/components23.dtd">
<components>
    <component name="greeting"
        class="examples.di.impl.GreetingImpl"/>
    <component name="greetingClient"
        class="examples.di.impl.GreetingClientImpl">
        <property name="greeting">greeting</property>
    </component>
</components>

実際にdiconファイルにどの実装クラスを利用するかcomponentタグを使って定義します。
Greetingインターフェイスには、GreetingImplクラスを、
GreetingClientインターフェイスには、GreetingClientImplクラスを定義しています。
そして、GreetingClientには、プロパティとしてgreetingが存在します。(setGreeting,getGreetingのところです)このプロパティに、上の行で指定したgreetingつまりこの設定ではGreetingImplを渡すDI設定となっています。

GreetingMain2.javaは、DIコンテナを使います。

GreetingClient greetingClient = (GreetingClient)
            container.getComponent("greetingClient");

コンポーネントの引き出しは、getComponentです。diconファイルのgreetingClientを呼び出しています。今回の設定では、GreetingClientImplが返されます。

diconファイルを変更すればコンポーネント間の結合条件は簡単に変更できます。つまり、疎結合が実現できて変更にも強い構造となります。

Seasar2で学ぶ DIとAOP アスペクト指向によるJava開発

Seasar2で学ぶ DIとAOP アスペクト指向によるJava開発