5

我有以下使用 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的两个命名 s 获取一个对象。Foo基本上,它应该以某种方式将@NamedonFoo与 on连接起来Bar。我尝试了几种解决方案,从穿上@Named一切到编写自定义Provider. 后者不起作用,因为我无权访问@Named提供程序中注释的值。我认为解决方案在某处bind(Bar.class).to(BarImpl.class);,告诉它记住@Named注释的值。

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

4

1 回答 1

12

它正在使用PrivateModules。基本上:

默认情况下,私有模块的配置信息对其环境是隐藏的。只有显式公开的绑定才可用于其他模块和注入器的用户。有关更多说明,请参阅此常见问题解答条目

以下是您的使用方法:

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 的强大功能,相同的依赖项具有不同的实现绑定。

希望这是有道理的。

于 2013-06-08T05:01:20.697 回答