0

ChildPlugin という子モジュールがあり、次のようにメイン モジュールからクラスを挿入します。

public class ChildPlugin {
    private ExampleClass demo;

    @Inject
    public void setDemo(ExampleClass demo) { 
        this.demo = demo;
    }
}

問題は、メイン モジュールがバインドされているかどうかがわからず、バインドExampleClassされていない場合、インジェクターの作成時に Guice が例外をスローすることです。私がやりたいことは、Guice を渡すことnull、またはOptional.emptyExampleClass がバインドされていない場合です。

メイン モジュールにアクセスできないため、バインダーを に変更できませんExampleClass。方法OptionalBinderを試し@NullableてみOptional<ExampleClass>ましChildPlugin.setDemoたが、うまくいきませんでした。

4

1 に答える 1

5

これを行うには 2 つの方法があります。

オプションの注入

com.google.inject.Inject アノテーションを使用します。これにより、注釈にオプションを指定できます。次の例を参照してください。

public class GuiceInjectOptional extends AbstractModule {

    @Override
    protected void configure() {

        // method 1: 
        bind(B.class).in(Singleton.class);

    }

    public static class A {

        private String name;
        // non null constructor so that A can't be instantiated automatically by guice
        public A(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "I am: " + name;
        }
    }

    public static class B {

        @Inject(optional=true)
        A obj;

        void run() {
            System.out.println("Object is: " + obj);
        }
    }

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

}

クラス B の注釈は、A がオプションであることを示しています。注射されません。スニペットを実行すると、次のように出力されます。

Object is: null

方法 2 (これは Guice 4+ の後に行う方法です)。オプションのバインディングを指定できます。これらのバインドでは、必要に応じてデフォルト値を定義することもできます。次に、私が書いたこのスニペットのように、オプションの値を挿入できます。

public class GuiceInjectOptional extends AbstractModule {

    @Override
    protected void configure() {
        // set up optional binding for A.
        OptionalBinder.newOptionalBinder(binder(), A.class);

        bind(B.class).in(Singleton.class);
    }

    public static class A {

        private String name;
        // non null constructor so that A can't be instantiated automatically by guice
        public A(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "I am: " + name;
        }
    }

    public static class B {

        @Inject
        Optional<A> obj;

        void run() {
            System.out.println("Object is present: " + obj.isPresent());
            System.out.println("Object is: " + obj);
        }
    }

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

}

Inject アノテーションはオプションではなくなりましたが、guice はクラス A がバインドされている場合とされていない場合があることを認識しています。スニペットを実行すると、次のように出力されます。

Object is present: false
Object is: Optional.empty

最後に、通常どおり A をバインドするだけで、guice がそれを挿入します。

public class GuiceInjectOptional extends AbstractModule {

    @Override
    protected void configure() {
        // set up optional binding for A.
        OptionalBinder.newOptionalBinder(binder(), A.class);

        bind(A.class).toInstance(new A("Pandaa!"));
        bind(B.class).in(Singleton.class);
    }

    public static class A {

        private String name;
        // non null constructor so that A can't be instantiated automatically by guice
        public A(String name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "I am: " + name;
        }
    }

    public static class B {

        @Inject
        Optional<A> obj;

        void run() {
            System.out.println("Object is present: " + obj.isPresent());
            System.out.println("Object is: " + obj);
        }
    }

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

}

そして、上記は印刷されます:

Object is present: true
Object is: Optional[I am: Pandaa!]

そして、これは、guice を使用してフェイルセーフなオプションのバインディングを作成する方法です :) これがお役に立てば幸いです。

編集: guice-3 タグを見たので、オプションのバインダーではなく、オプションの注釈メソッドを使用することをお勧めします。オプションの注釈を使用すると、オプションの値ではなく null のままになります。

アルトゥール

于 2016-08-12T09:44:22.793 に答える