Java Guice-“动态”绑定? 请考虑下面的代码片段: // some class, somewhere - CANNOT MODIFY IT public class SystemOutPrinter implements Printer { private final String prefix; private final String suffix; @Inject public Printer( @Named("prefix") String prefix, @Named("suffix") String suffix) { this.prefix = prefix; this.suffix = suffix; } @Override public void print(String line) { System.out.println(prefix + line + suffix); } } ... // my "regular" binding, in some module bind(Key.get(String.class, Names.named("prefix"))).toInstance("> "); ... // runtime-provided values: Class<? extends Printer> printerClass = SystemOutPrinter.class; Key<String> suffixKey = Key.get(String.class, Names.named("suffix")); // my "dynamic" binding, probably in runtime Printer shouter = instantiate(printerClass, suffixKey, "!"); Printer asker = instantiate(printerClass, suffixKey, "?"); ... // the example usage of the above guice-injected Printers shouter.print("test"); asker.print("test"); // the expected output: // > test! // > test?

Java Guice-“动态”绑定? 请考虑下面的代码片段: // some class, somewhere - CANNOT MODIFY IT public class SystemOutPrinter implements Printer { private final String prefix; private final String suffix; @Inject public Printer( @Named("prefix") String prefix, @Named("suffix") String suffix) { this.prefix = prefix; this.suffix = suffix; } @Override public void print(String line) { System.out.println(prefix + line + suffix); } } ... // my "regular" binding, in some module bind(Key.get(String.class, Names.named("prefix"))).toInstance("> "); ... // runtime-provided values: Class<? extends Printer> printerClass = SystemOutPrinter.class; Key<String> suffixKey = Key.get(String.class, Names.named("suffix")); // my "dynamic" binding, probably in runtime Printer shouter = instantiate(printerClass, suffixKey, "!"); Printer asker = instantiate(printerClass, suffixKey, "?"); ... // the example usage of the above guice-injected Printers shouter.print("test"); asker.print("test"); // the expected output: // > test! // > test?,java,dependency-injection,scope,guice,Java,Dependency Injection,Scope,Guice,正如您所看到的,我需要注入一个全局前缀,这很简单,还需要一个每个实例的后缀。通常在这种情况下,我会将@AssistedInject与Factory.createString后缀方法一起使用-但在这种情况下,我不能,因为SystemOutPrinter类无法修改。请假设我甚至不知道它的来源。我得到的只是一个参考运行时!一个printerClass和一个后缀键及其值!或在运行时,我甚至不知道后缀的绑定注释是什么样子。我需要做的就是实现这个方法: public static <T> T i

正如您所看到的,我需要注入一个全局前缀,这很简单,还需要一个每个实例的后缀。通常在这种情况下,我会将@AssistedInject与Factory.createString后缀方法一起使用-但在这种情况下,我不能,因为SystemOutPrinter类无法修改。请假设我甚至不知道它的来源。我得到的只是一个参考运行时!一个printerClass和一个后缀键及其值!或在运行时,我甚至不知道后缀的绑定注释是什么样子。我需要做的就是实现这个方法:

public static <T> T instantiate(Class<? extends T> cls, Key<String> key, String value) {
  ...?
}
这可以通过在实例化方法中构造每个实例的childInjector来实现。请假设我有一个Injector实例,但显然这是一个非常昂贵的操作,最长可达毫秒,对于我的Injector,我负担不起。我希望使用自定义范围可以实现,但无法让它们工作


有什么想法吗?

为什么不自己写工厂呢

public class SystemOutPrinterFactory {
  private final String prefix;

  public SystemOutPrinterFactory(@Named("prefix") String prefix) {
    this.prefix = prefix;
  }

  public SystemOutPrinter createWithSuffix(String suffix) {
    return new SystemOutPrinter(prefix, suffix);
  }
}
SystemOutPrinter类是公共的,非抽象的,带有公共构造函数,因此应该可以工作。唯一的缺点是工厂需要知道具体的实现

如果您不知道实现类,那么您将需要一个子注入器,但是假设这些类是线程安全的,您可以使用来避免创建子注入器超过两次