Google Guice(その4) メソッドやコンストラクタへのInject指定
その2で書いたコードでは、下記のようにフィールドに@Injectを宣言してInjectしてました。
@Inject private Service service;
GuiceはもちろんメソッドやコンストラクタにもInject出来ます。
import sample.guice.service.Service; import com.google.inject.Inject; public class InjectSample { // フィールド @Inject private Service service; // コンストラクタ @Inject public InjectSample(Service service) { System.out.println("コンストラクタ <" + service + ">"); } // メソッド @Inject public void injectedMethod(Service service) { System.out.println("メソッド <" + service + ">"); } public void execute() { System.out.println("フィールド <" + service + ">"); } }
public class InjectSampleMain { // 起動 public static void main(String[] args) { Injector injector = Guice.createInjector(new AbstractModule() { protected void configure() { bind(Service.class).to(ServiceImpl.class); } }); InjectSample injectSample = injector.getInstance(InjectSample.class); injectSample.execute(); } }
これを実行すると、
コンストラクタ
メソッド
フィールド
となり、全てInjectされているのが分かります。*1
また見ての通りメソッドはsetterであるかどうかに関係ありません。User's Guideにも「setterとか関係ないし」と書いてあります。
なお同じところに、「パラメータが複数でもOK。@InjectがスーパークラスにあってもOK」と書いてあるので、もうちょっと試してみましょう。
まず適当なサブクラス。
public class InjectSample extends AbstractInjectSample { @Inject public InjectSample(Service service) { super(service, "dummy"); System.out.println("コンストラクタ <" + service + ">"); } @Inject public void injectedMethod(String dummy, Service service) { System.out.println("メソッド <" + service + ">"); } }
次に適当なスーパークラス。
import sample.guice.service.Service; import com.google.inject.Inject; public abstract class AbstractInjectSample { @Inject private Service superService; @Inject public AbstractInjectSample(Service service, String dummy) { System.out.println("スーパークラスのコンストラクタ <" + service + ">"); } @Inject public void superInjectedMethod(String dummy, Service service) { System.out.println("スーパークラスのメソッド <" + service + ">"); } public void superExecute() { System.out.println("スーパークラスのフィールド <" + superService + ">"); } }
実行すると、
と出ました。確かに他の引数があってもOK、スーパークラスもちゃんと処理されています。