Android+Guice その3

※2012・10 こちらのページにまとめるようにしてみました。

今回はScope編。といってもSingletonにするってだけですが。

前回getInstance()でインスタンスを取得しましたけど、

を実行したら結果はどうなるでしょう?

答えはclient1とclient2は それぞれ別instanceが作成されて戻ります。

Guiceでは特に指定しない限りはこれがデフォルトの動作でgetInstance()される度にインスタンスを作ってくれます。これはClientに注入されたServiceImplについても同じです。

インスタンスを全体で一つに制限してSingletonにしたい場合いくつかの方法があります。

一つ目はSingletonにしたいConcrete Classに対して@Singletonアノテーションを追加します。

これでSingletonになります。

ただ、この方法は別の実装を作ったときに@Singletonを忘れてしまって、実装を切り替えた時に挙動が異なってしまう危険がある様に思います。

@Singletonアノテーションは ソースファイル上で「これはSingletonだよ!」という実装者へのマーク程度と考えて(それでも書いておいた方が良いです)、Moduleのconfigure()内でin(Singleton.class)を併用するのが良いのかなと個人的には思ってます。

ちなみに今回の場合は以下のように一行で書けますが複数Interfaceを実装している場合に注意が必要です。

以下の場合はService.classが要求された時と、Another.classが要求された時に それぞれでInstanceが作成され、2つのInstanceが作成されることになります。

前回のソースを変更してSingletonで作られている事を確認しましょう。

まずはSingletonである事の宣言

続いてClientのServiceにアクセスできるように作られたオブジェクトの数を数えるのとServiceを比較できるようにgetterを追加。

最後にMainを書き換えてSingletonかどうかを確認します。

Service.javaとOkinawaModule.javaは昨日のと同じです。

さて実行してみましょう。

この通りServiceImplはインスタンスが一つしか作成されずSingletonになっています。

ServiceImpl.javaの@Singletonをはずして、OkinawaModule.javaを以下の様に書き換えても同じ様な結果が得られます。

次回はSingletonの初期化タイミングについて