2

私は、FactoryModuleBuilder を使用して Guice で支援された注入を実装する方法を理解しようとしている Guice 初心者です。FactoryModuleBuilderの実装については、Guice Java ドキュメントを参照しました。

ドキュメントに記載されているとおりにすべてを行いました。工場に注入していません。このスタック オーバーフローの質問を参照しました。Guice AssistedInject は、同じ問題が発生したファクトリを注入しません。コンストラクター注入問題の前のフィールド注入について話します。私はそれに従い、呼び出し元クラスを使用して親クラスを呼び出そうとしていますが、まだヌルポインター例外が発生しています。ここで何がうまくいかないのですか?

呼び出し元クラス

public class MAIN {

    @Inject private static MyFactory factory;

    public static void main(String[] args){
        ParentClass newbie = new ParentClass(factory);
    }
}

私はまだ例外を取得しています:

Exception in thread "main" java.lang.NullPointerException
    at com.pkg.ParentClass.<init>(ParentClass.java:19)
    at com.pkg.MAIN.main(MAIN.java:10)

親クラス

public class ParentClass {

    private final Foo test;
    @Inject
    public ParentClass(MyFactory factory){
        test = factory.create(new HashMap<String,Object>());
    }
}

モジュールの実装: ParentModule

public class ParentModule extends AbstractModule{

    @Override
    protected void configure() {
        install(new FactoryModuleBuilder()
                .implement(Foo.class, FooImpl.class)
                .build(MyFactory.class));
    }

}

工場インターフェース: MyFactory

public interface MyFactory {

    Foo create(Map<String,Object> map);
}

クラス インターフェイス : Foo

public interface Foo{
}

クラス:FooImpl

public class FooImpl implements Foo {

    private final Map<String,Object> mapA;
    @AssistedInject
    public FooImpl(@Assisted Map<String,Object> map){

        mapA=map;
    }

}
4

1 に答える 1

3

ここで 2 つの問題があります。

まず最も重要なことは、あなたはInjectorどこにも創造していないということです。明らかに、注射器なしでは何も機能しません。モジュールを使用してインジェクター インスタンスを作成する必要があります。

Injector injector = Guice.createInjector(new ParentModule());

2 番目の問題は、ファクトリを静的フィールドに挿入することです。

@Inject private static MyFactory factory;

明示的に指定すれば、Guice は static フィールドを扱うことができますが、それは非常に悪い習慣と考えられています。レガシー コードを使用している場合を除き、静的フィールドに注入しないでください。

あなたが本当に欲しいのは次のようなものです:

public class Main {
    @Inject
    private MyFactory factory;

    public void run() {
        ParentClass newbie = new ParentClass(factory);
    }

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new ParentModule());
        Main main = injector.getInstance(Main.class);
        main.run();
    }
}

プログラム エントリ ポイント ( main) はインジェクターを作成し、それを使用してクラスのインスタンスを作成することに注意してくださいMain。これにより、そのフィールドが自動的に注入されます。そして、run()実際の作業を行うインスタンスのメソッドを呼び出します。

ただし、これはすべて、アシスト インジェクションを説明する目的でのみ実際に有効であることに注意してください。実際のコードをこのように構成しないでください。たとえば、newoperator を使用して、コンストラクターに@Inject. これは絶対にしないでください!一部のクラス (つまり、そのコンストラクターまたはフィールド) を有効としてマークする場合@Inject、このクラスはインジェクションによってのみ使用する必要があります。コードMainは次のように短縮できます。

public class Main {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new ParentModule());
        ParentClass newbie = injector.getInstance(ParentClass.class);
    }
}

Hereは、 の注釈が付けられているため、コンストラクターにnewbieのインスタンスを自動的に受け取ります。MyFactory@Inject

そして、私はすでに静的について書きました。

于 2013-05-22T11:21:02.030 に答える