Java Guice和;“范围”;单身汉
我试图学习Guice,但下面的场景似乎很难。假设我有A、B和C类。我应该能够做到以下几点(注意,这个例子在某种程度上简化为实际情况):Java Guice和;“范围”;单身汉,java,dependency-injection,guice,Java,Dependency Injection,Guice,我试图学习Guice,但下面的场景似乎很难。假设我有A、B和C类。我应该能够做到以下几点(注意,这个例子在某种程度上简化为实际情况): A是全局单例 A依赖于供应商B(即工厂) B依赖于A和供应商C(即工厂) C依赖于A和B 当B创建C时,C的依赖项B必须是同一个实例,即从C的角度来看,B是单例的 我尝试过创建儿童注射器: private static class MainModule extends AbstractModule{ @Override protected vo
private static class MainModule extends AbstractModule{
@Override
protected void configure() {
bind(A.class).in(Singleton.class);
}
@Provides
B createB(Injector injector){
return injector.createChildInjector(new SubModule()).getInstance(B.class);
}
}
private static class SubModule extends AbstractModule{
@Override
protected void configure() {
bind(B.class).in(Singleton.class);
bind(C.class);
}
}
public static void main(String[] args) {
Injector injector = Guice.createInjector(new MainModule());
A a = injector.getInstance(A.class);
B b1 = a.getB();
B b2 = a.getB();
// all following C's are different instances
C b1c1 = b1.getC(); //this has b1 and a
C b1c2 = b1.getC(); //this has b1 and a
C b2c1 = b2.getC(); //this has b2 and a
C b2c2 = b2.getC(); //this has b2 and a
}
但是Guice给出了B已经绑定的错误(MainModule中提供了方法)。因此,我需要覆盖MainModule的B绑定,但这似乎不可能使用子注入器
该问题可以通过使用多个喷油器来解决,例如,为createB方法创建一个新喷油器,并将喷油器A作为参数,但使用多个喷油器似乎不是最佳做法
编辑:在C实例中添加注释,以澄清它们应该具有哪个B实例我将发布此作为一个答案,它更像是解决方案,而不是完整的解决方案,但对于我的应用程序来说可能已经足够好了:
private static class MainModule extends AbstractModule{
@Override
protected void configure() {
bind(A.class).in(Singleton.class);
bind(SubModule.class).in(Singleton.class);
}
@Provides
B createB(Injector injector){
SubModule m = injector.getInstance(SubModule.class);
return Guice.createInjector(m).getInstance(B.class);
}
}
private static class SubModule extends AbstractModule{
private final A a;
@Inject
public SubModule(A a) {
this.a = a;
}
@Override
protected void configure() {
bind(A.class).toInstance(a);
bind(B.class).in(Singleton.class);
bind(C.class);
}
}
首先,我认为大多数绑定都在main模块中,但我想如果它们只在B的上下文中使用(并像我在A中那样路由其他绑定),那么它们无论如何都可以移动到子模块。这与链接问题的答案大致相似:
但我创建了新的顶级注入器,因为我似乎无法在两个模块中绑定B,否则我可能会错过一些东西
(第一次这样做,不确定这是否是正确的方法,将一个变通方法作为自己的答案发布)是否有一个原因,主模块和子模块不能同时安装到初始注入器中,或者您不能用
@Singleton
注释@提供了createB(…)
?嗯,可能我有点不清楚,如果我说,对于B的每个依赖项,B都被认为是单例的,但是其他地方可能有多个B,也就是说,每次调用A.getB时,它都返回一个新实例,这是否更清楚。如果我用@Singleton注释createB,我想B在任何地方都会被视为单例。我还可以注意到父注入器到目前为止只有单例绑定(这里是A,在实际应用中更多),因此我可以用父注入器创建子模块,注入每个单例,再次将它们作为单例绑定,并在创建B之前创建全新的顶级注入器,但我希望避免再次编写它们。您可能希望研究辅助注入器。因此,与其使用B
提供程序,不如使用CFactory
,并将其称为工厂。创建(此)
。您的问题是否与“”相关?