1

Guice 3.0 を使用しようとしてAssistedInjectいますが、ファクトリがインスタンス化されません。

SSCCE コード:

親クラス

public class ParentClass() {
  @Inject private MyFactory myFactory;
  private final Foo foo;
  private final Bar bar;
  public ParentClass() {
    if(myFactory == null) System.err.println("Error: I should have injected by now!");
    foo = myFactory.create(new Map<String, Object>());
    // etc.
  }
}

工場インターフェース

public interface MyFactory {
  Foo create(Map<String, Object> mapA);
  Bar create(Map<String, Object> mapB, Map<String, Object> mapC);
}

モジュール

public class ParentModule extends AbstractModule {
  @Override
  protected void configure() {
    install(new FactoryModuleBuilder()
        .implement(Foo.class, FooImpl.class)
        .implement(Bar.class, BarImpl.class)
        .build(MyFactory.class));
  }

FooImpl

public class FooImpl implements Foo {
  private final Map<String, Object> mapA;
  @AssistedInject
  public FooImpl(@Assisted Map<String, Object> mapA) {
    this.mapA = mapA;
  }
}

BarImplに非常によく似ていFooImplます。ここで何がうまくいかないのですか?@AssistedInject私は両方と@Injectここで試したことにも注意してください。両方ともエラーが発生します。

出力:

Error: I should have injected by now!
Exception in thread "main" com.google.inject.ProvisionException: Guice provision errors:

1) Error injecting constructor, java.lang.NullPointerException
  at ParentClass.<init>(ParentClass.java:7)
  while locating com.my.package.ParentClass

1 error
        at com.google.inject.internal.InjectorImpl$4.get(InjectorImpl.java:987)
        at com.google.inject.internal.InjectorImpl.getInstance(InjectorImpl.java:1013)
        at com.my.package.ParentMain.main(ParentMain.java:16)
Caused by: java.lang.NullPointerException
        at com.my.package.ParentClass.<init>(ParentClass.java:9)
        at com.my.package.ParentClass$$FastClassByGuice$$d4b3063a.newInstance(<generated>)
        at com.google.inject.internal.cglib.reflect.$FastConstructor.newInstance(FastConstructor.java:40)
        ... 8 more

行 9 は、への最初の呼び出しの行であることに注意してください。myFactory.create()

4

2 に答える 2

6

Guice のjavadocによると、フィールド インジェクションはコンストラクタ インジェクションの後に実行されます。

あなたのParentClassインスタンスは Guice によって作成されたと思います。ParentClassのコンストラクターが実行されるとき、そのフィールドmyFactoryはまだ注入されていません。

于 2013-02-07T20:45:17.383 に答える
3

2つのこと。コンストラクターでインジェクションを使用するには、コンストラクターインジェクションを使用する必要があります。

public class ParentClass {

    private final Foo foo;
    private final Bar bar;

    @Inject
    public ParentClass(MyFactory myFactory) {
        if(myFactory == null) System.err.println("Error: I should have injected by now!");
        this.foo = myFactory.create(new HashMap<String, Object>());
        this.bar = myFactory.create(new HashMap<String, Object>(), new HashMap<String, Object>());
    }
}

また、ファクトリには同じタイプの2つのパラメータがあるため、次の名前を付ける必要があります。

public interface MyFactory {
    Foo create(Map<String, Object> mapA);
    Bar create(@Assisted("B") Map<String, Object> mapB, @Assisted("C") Map<String, Object> mapC);
}

public class BarImpl implements Bar {

    private final Map<String, Object> mapA;
    private final Map<String, Object> mapB;

    @AssistedInject
    public BarImpl(@Assisted("B") Map<String, Object> mapA, @Assisted("C")  Map<String, Object> mapB) {
        this.mapA = mapA;
        this.mapB =mapB;
    }
}
于 2013-02-07T20:49:15.500 に答える