子模块的故障安全注入器.google guice中的可选绑定



我有一个名为ChildPlugin的子模块,我从主模块注入类如下:

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

问题是,我不知道主模块是否绑定了ExampleClass,如果它不是Guice在创建注入器时抛出异常。我想做的是让Guice传递nullOptional.empty,如果ExampleClass没有绑定。

我无法访问主模块,所以我不能将ExampleClass的粘合剂更改为OptionalBinder,我尝试了@NullableOptional<ExampleClass>ChildPlugin.setDemo方法中,但它不起作用。

有两种方法可以做到这一点。

可选注入

使用com.google.inject.Inject注释。它允许您在注释上指定optional。请看下面的例子:

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(这是您在指南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获得故障安全的可选绑定:)我希望这对你有帮助。

编辑:我刚刚看到了guide -3标签,所以你会想要使用可选的注释方法而不是可选的绑定器。使用可选注释,它将保持为空,而不是可选值。

阿图尔

最新更新