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、スーパークラスもちゃんと処理されています。

*1:ついでに、デフォルトでは毎回インスタンスを生成してる事も分かります