这是一个基于原始代码的解决方案-进行了三处更改:
- 将A,C和D的绑定移到单独的子模块中
- 在子模块中将A标记为单例
- 在主模块中使用@Provides方法为BImpl的实例提供
每个请求的新子注入器-这是子模块所在的位置
之所以可行,是因为A的单例绑定现在仅限于每个子注入器。
[注意:
如果您不想一直为B的每个请求创建子模块实例,则可以始终将子模块实例缓存在主模块的字段中。
import java.util.*; import com.google.inject.*; public class Main { public static class Super { private static Map<Class<?>,Integer> map = new HashMap<Class<?>,Integer>(); private Integer value; public Super(Object... args) { value = map.get(getClass()); value = value == null ? 0 : ++value; map.put(getClass(), value); if(args.length > 0) System.out.println("Created " + this + " with " + Arrays.toString(args)); } @Override public final String toString() { return "" + getClass().getSimpleName().charAt(0) + value; } } public interface A { } public static class AImpl extends Super implements A { } public interface B { } public static class BImpl extends Super implements B { @Inject public BImpl(C c, D d) { super(c,d); } } public interface C { } public static class CImpl extends Super implements C { @Inject public CImpl(A a) { super(a); } } public interface D { } public static class DImpl extends Super implements D { @Inject public DImpl(A a) { super(a); } } public static class MyModule extends AbstractModule { @Override protected void configure() {} // >>>>>>>> @Provides B builder( Injector injector ) { return injector.createChildInjector( new SubModule() ).getInstance( BImpl.class ); } // <<<<<<<< } // >>>>>>>> public static class SubModule extends AbstractModule { @Override protected void configure() { bind(A.class).to(AImpl.class).in( Scopes.SINGLETON ); bind(C.class).to(CImpl.class); bind(D.class).to(DImpl.class); } } // <<<<<<<< public static void main(String[] args) { Injector inj = Guice.createInjector(new MyModule()); inj.getInstance(B.class); inj.getInstance(B.class); } }


