我有以下情况:
public class InjectionTest {
private static class Sub {
@Inject private final String value = null;
}
private static class General {
@Inject private final Sub sub = null;
}
private static class MainOne {
@Inject private final General general = null;
}
private static class MainTwo {
@Inject private final General general = null;
}
public static void main(String... arguments) {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override protected void configure() {
/* DO MAGIC */
}
});
MainOne mainOne = injector.getInstance(MainOne.class);
MainTwo mainTwo = injector.getInstance(MainTwo.class);
assertThat(mainOne.general.sub.value, is("one"));
assertThat(mainTwo.general.sub.value, is("two"));
}
}
我希望可从 MainOne
实例访问的 value
为 "one"
并且 value
可访问从 MainTwo
实例变为 "two"
。我尝试过以下方法:
- 使用Guice的
Named
注释;不幸的是,这需要我自己创建General
实例或使用子注入(inject)器来创建Sub
实例。 - 使用 Guice 的
Scope
机制。我无法真正让它按照我想要的方式工作,并且感觉它从来没有打算这样做,事实上甚至根本无法这样做。
(当然,真实的场景一如既往地更复杂:我有一个 GuiceServletContextListener
和一个 ServletModule
并且我正在尝试重用几个类/服务在所有创建的 Servlet
实例中,但还需要一些从 servlet 请求的专用模块。)
我错过了什么吗?有没有(相对)简单的方法来实现我想要的?
最佳答案
首先,您不应该注入(inject)最终字段(请参阅评论)。我建议您删除 final
修饰符,或使用构造函数注入(inject)。
可以使用私有(private)模块来解决您的示例。但我不认为这是一个“简单”的解决方案。
Injector injector = Guice.createInjector(new PrivateModule() {
@Override
protected void configure() {
bind(String.class).toInstance("one");
bind(MainOne.class);
expose(MainOne.class);
}
}, new PrivateModule() {
@Override
protected void configure() {
bind(String.class).toInstance("two");
bind(MainTwo.class);
expose(MainTwo.class);
}
});
我认为您最好使用 @Named
或创建自己的绑定(bind)注释。
另请阅读有关“机器人腿”问题的 wiki 页面: https://github.com/google/guice/wiki/FrequentlyAskedQuestions#how-do-i-build-two-similar-but-slightly-different-trees-of-objects
关于java - 根据要注入(inject)的对象注入(inject)值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26712661/