我使用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
Foo
与Bar
上的@Named
连接起来。我尝试了几种解决方案,从将Provider
放在所有内容上,再到编写自定义@Named
。后者不起作用,因为我无法访问提供程序中bind(Bar.class).to(BarImpl.class);
注释的值。我认为解决方案位于行@Named
中的某个位置,告诉它记住{{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的强大功能对同一个依赖项有不同的实现限制。
希望它有意义。