注入命名吉斯单
我有一个简单的POJO:注入命名吉斯单
public class MyPOJO {
@Inject
private Fizz fizz;
private Buzz buzz;
// rest of class omitted for brevity
}
我想配置我吉斯模块,有两种类型的Fizz
ES,这注入:
- 一个特殊的, global-singleton
Fizz
instance;和 - 其他(非特殊)
Fizz
实例
我想MyPOJO
与特殊/单实例注入。所以,我修改了代码:
public class MyPOJO {
@Inject @Named("Special-Fizz")
private Fizz fizz;
private Buzz buzz;
// rest of class omitted for brevity
}
然后我的模块中:
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);
}
}
但是,当我试图单元测试(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);
}
}
此通过。到现在为止还挺好。不过,如果我改变specialFizz
字段的名称:
@Named("Special-Fuzz-This-Shouldnt-Work") private Fizz specialFizz;
,并重新运行测试,它仍然通过。为什么?!?我在哪里误入歧途?提前致谢。
很奇怪。 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);
}
}
Guice看到@Provides
方法,并愉快地使用它来注入Fizz
。如果你想拥有的Fizz
一个特例,您可以从providesFizz()
方法删除注释,而是与
bind(Fizz.class)
.annotatedWith(Names.named("Special-Fizz")
.toInstance(providesFizz());
这样绑定,你告诉吉斯正好为“特殊菲斯”使用的Fizz
,同时仍然让它注入Fizz
否则“正常”。
声明:我没有真正尝试像你这样的设置,但我使用了一个类似的设置。让我知道它是否有效。
Thanks @Bradley T. Hughes(+1) - **然而**您的建议不会改变任何内容。单元测试仍然通过,不管你命名'Fizz'。你提到了一些我认为很有趣的东西。你说过“*我实际上没有尝试像你这样的设置......”,但是,从你的回答中我推断出你使用Guice似乎很舒服。所以这让我想知道:*这是一个奇怪的设置,我正在使用?*我认为Guice的*点*是使用Classes和Annotations一起准确地确定你想要注入什么类型/配置... – IAmYourFaja 2013-02-09 01:43:23
..那么我在这里做的事与众不同?如果是这样,为什么?!?我在哪里误解Guice的正常用法?再次感谢! – IAmYourFaja 2013-02-09 01:44:07
我不认为这是一个奇怪的设置。说实话,我还没有使用过Guice,所以我当然不是专家。不同的是,我正在使用的代码使用相同的注释来注入两种不同的类型(每个类型的单个实例)。 – 2013-02-09 19:38:06
Thanks @condit(+1) - 这是我在输入这个问题时的一个错误。我编辑了我的原始问题,以表明我实际上调用了'injector.getInstance',而不是'injector.inject'。这会为你改变什么吗? 'getInstance'不正确,我在这里使用?如果是这样,为什么,什么是?再次感谢! – IAmYourFaja 2013-02-09 02:03:56
在你测试你问喷射器Fizz'的'一个实例,它始终能为您提供(因为你'@ Provides'方法)。我想你想得到一个'MyPOJO'的实例。请注意,你得到的'Fizz'与测试中的'Fizz'成员无关。所以在这种情况下更改'@ Named'将不起作用。 – condit 2013-02-09 02:05:50
你钉了它。我只是要求它注入一个'MyPOJO',并且正确地向它的'Fizz'属性注入了特殊的嘶嘶声。神秘解决 - 只是一个执行不力的测试方法。再次感谢! – IAmYourFaja 2013-02-09 02:09:07