Guice:绑定具有不同依赖关系的多个对象

时间:2013-06-07 15:32:08

标签: java guice

我使用Guice绑定代码如下:

public class MyApplication {
    public static void main(String[] args) {
        Guice.createInjector(new AbstractModule() {
            @Override
            protected void configure() {
                bind(Foo.class).annotatedWith(Names.named("first")).toInstance(new Foo("firstFoo"));
                bind(Foo.class).annotatedWith(Names.named("second")).toInstance(new Foo("secondFoo"));

                bind(Bar.class).to(BarImpl.class);

                bind(MyApplication.class).asEagerSingleton();
            }
        });
    }

    private @Named("first") Bar first;
    private @Named("second") Bar second;

    static @Value class Foo { String name; }
    static interface Bar {}

    static class BarImpl implements Bar {
        @Inject @Named Foo foo;
    }
}

我正在尝试为我的应用程序中注入的两个命名Bar获取Foo个对象。基本上,它应该以某种方式将@Named FooBar上的@Named连接起来。我尝试了几种解决方案,从将Provider放在所有内容上,再到编写自定义@Named。后者不起作用,因为我无法访问提供程序中bind(Bar.class).to(BarImpl.class);注释的值。我认为解决方案位于行@Named中的某个位置,告诉它记住{{1}}注释的值。

我的问题是,这有可能吗?如果是的话,怎么样?

1 个答案:

答案 0 :(得分:11)

正在使用PrivateModules。基本上是:

默认情况下,私有模块的配置信息对其环境是隐藏的。只有明确公开的绑定才可用于其他模块和注入器的用户。有关详细说明,请参阅this FAQ entry

以下是您使用它的方式:

protected void configure() {
    install(new PrivateModule() {
        @Override
        protected void configure() {
            // #bind makes bindings internal to this module unlike using AbstractModule
            // this binding only applies to bindings inside this module
            bind(Foo.class).toInstance(new Foo("first"));
            // Bar's foo dependency will use the preceding binding
            bind(Bar.class).annotatedWith(Names.named("first")).to(BarImpl.class);
            // if we'd stop here, this would be useless
            // but the key method here is #expose
            // it makes a binding visible outside as if we did AbstractModule#bind
            // but the binding that is exposed can use "private" bindings
            // in addition to the inherited bindings              
            expose(Bar.class).annotatedWith(Names.named("first"));
        }
    });
    install(new PrivateModule() {
        @Override
        protected void configure() {
            bind(Foo.class).toInstance(new Foo("second"));
            bind(Bar.class).annotatedWith(Names.named("second")).to(BarImpl.class);
            expose(Bar.class).annotatedWith(Names.named("second"));
        }
    });
         bind(MyApplication.class).asEagerSingleton();
    }
}

现在你有效地拥有2个条,每个条看起来像

static class BarImpl implements Bar {
    @Inject Foo foo;
}

但是PrivateModules的强大功能对同一个依赖项有不同的实现限制。

希望它有意义。