java 注入命名 Guice 单例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14781771/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Injecting named Guice singleton
提问by IAmYourFaja
I have a simple POJO:
我有一个简单的 POJO:
public class MyPOJO {
@Inject
private Fizz fizz;
private Buzz buzz;
// rest of class omitted for brevity
}
I would like to configure my Guice module such that there are two types of Fizz
es that it injects:
我想配置我的 Guice 模块,Fizz
以便它注入两种类型的es:
- A special, globally-singleton
Fizz
instance; and - Other (non-special)
Fizz
instances
- 一个特殊的全局单例
Fizz
实例;和 - 其他(非特殊)
Fizz
实例
I want MyPOJO
to be injected with the special/singleton instance. So I modified my code:
我想MyPOJO
注入特殊/单例实例。所以我修改了我的代码:
public class MyPOJO {
@Inject @Named("Special-Fizz")
private Fizz fizz;
private Buzz buzz;
// rest of class omitted for brevity
}
Then in my module:
然后在我的模块中:
public class MyModule extends AbstractModule {
@Override
public void configure() {
bind(Fizz.class).annotatedWith(
Names.named("Special-Fizz"))
.to(Fizz.class);
// Other bindings here...
}
@Provides @Singleton
private Fizz providesFizz() {
return new Fizz(true, "Special", 12.0);
}
}
But when I try to unit test (JUnit 4.10) this:
但是当我尝试单元测试(JUnit 4.10)时:
public class MyTest {
@Named("Special-Fizz") private Fizz specialFizz;
@Test
public void usingNamedShouldInjectSpecialFizz() {
MyModule mod = new MyModule();
Injector injector = Guice.createInjector(mod);
specialFizz = injector.getInstance(Fizz.class);
Assert.assertTrue(specialFizz != null);
}
}
This passes. So far, so good. But then if I change the name of the specialFizz
field:
这通过。到现在为止还挺好。但是,如果我更改specialFizz
字段的名称:
@Named("Special-Fuzz-This-Shouldnt-Work") private Fizz specialFizz;
And re-run the test, it still passes. Why?!? Where am I going astray here? Thanks in advance.
并重新运行测试,它仍然通过。为什么?!?我哪里会误入歧途?提前致谢。
采纳答案by condit
Very odd. Guice should complain if it can't find a Named
binding that it's injecting. I'm a bit confused by your test, though. I don't know what injector.inject
does. Do you mean injectMembers
? It might make more sense to actually get an instance of your POJO and make sure that it's working the way you expect. Maybe something like:
很奇怪。如果 Guice 找不到Named
它正在注入的绑定,它应该抱怨。不过,我对你的测试有点困惑。不知道有什么injector.inject
作用 你的意思是injectMembers
?实际获取您的 POJO 实例并确保它按您期望的方式工作可能更有意义。也许是这样的:
public class FizzTest {
public static class MyModule extends AbstractModule {
@Override
protected void configure() {
}
@Provides
@Singleton
@Named("Special-Fizz")
public Fizz providesFizz() {
return new Fizz(true);
}
}
public static class Fizz {
boolean special = false;
public Fizz() {}
public Fizz(boolean special) {
this.special = special;
}
}
public static class MyPOJO {
@Inject @Named("Special-Fizz")
private Fizz fizz;
@Inject
private Fizz otherFizz;
}
@Test
public void test() {
MyModule mod = new MyModule();
Injector injector = Guice.createInjector(mod);
MyPOJO pojo = injector.getInstance(MyPOJO.class);
assertTrue(pojo.fizz.special);
assertTrue(!pojo.otherFizz.special);
}
}
回答by Bradley T. Hughes
Guice sees the @Provides
method and happily uses that to inject the Fizz
. If you want to have a special instance of Fizz
, you can drop the annotations from the providesFizz()
method and instead bind with
Guice 看到了这个@Provides
方法,并愉快地使用它来注入Fizz
. 如果你想要一个特殊的 实例Fizz
,你可以从providesFizz()
方法中删除注释,而是绑定
bind(Fizz.class)
.annotatedWith(Names.named("Special-Fizz")
.toInstance(providesFizz());
This way, you tell Guice exactly which Fizz
to use as the "Special-Fizz", while still letting it inject Fizz
"normally" otherwise.
通过这种方式,您可以准确地告诉 Guice 将哪个Fizz
用作“Special-Fizz”,同时仍然让它Fizz
“正常”注入。
Disclaimer: I haven't actually tried a setup like yours, but I have used one similar. Let me know if it works or not.
免责声明:我实际上还没有尝试过像您这样的设置,但我使用过类似的设置。让我知道它是否有效。