Revision 2 as of 2009-12-13 23:28:30

Clear message
Locked History Actions

guice/ChildInjector

子インジェクタ

あるインジェクタの設定をすべて継承してそれを拡張する「子インジェクタ」というものを作成することができる。

基本的な使い方

public class ChildOne {
  public interface A {}
  public static class AImpl implements A {}
  public interface B {}
  public static class BImpl implements B {}
  
  public static void main(String[]args) {
    Injector injector = Guice.createInjector(new AbstractModule() {
      @Override protected void configure() {
        bind(A.class).to(AImpl.class);
      }
    });
    Injector child = injector.createChildInjector(new AbstractModule() {
      @Override protected void configure() {
        bind(B.class).to(BImpl.class);
      }
    });    
    System.out.println(injector.getInstance(A.class));
    System.out.println(child.getInstance(B.class));
    System.out.println(injector.getInstance(B.class));
  }
}

実行結果は

test.ChildOne$AImpl@1ac1fe4
test.ChildOne$BImpl@17f1ba3
Exception in thread "main" com.google.inject.ConfigurationException: Guice configuration errors:

1) A binding to test.ChildOne$B already exists on a child injector.
  while locating test.ChildOne$B

1 error
        at com.google.inject.InjectorImpl.getProvider(InjectorImpl.java:784)

つまり、子は親のバインディングをすべて継承するが、子で独自に作成したバインディングは親からは見えない。

親と同じバインディングを子で指定した場合

    Injector injector = Guice.createInjector(new AbstractModule() {
      @Override protected void configure() {
        bind(A.class).to(AImpl.class);
        bind(B.class).to(BImpl.class); // <-- ※
      }
    });
    Injector child = injector.createChildInjector(new AbstractModule() {
      @Override protected void configure() {
        bind(B.class).to(BImpl.class);
      }
    }); 

実行結果は以下になる。

Exception in thread "main" com.google.inject.CreationException: Guice creation errors:

1) A binding to test.ChildOne$B was already configured at test.ChildOne$1.configure(ChildOne.java:14).
  at test.ChildOne$2.configure(ChildOne.java:19)

親がバインディング解決を行う際には、それに先立ちすべての子のバインディングを調査するため、「※」の部分でエラーが発生する。

バインディングの解決を参照のこと。