有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

javaguice:命令行上的运行时注入/绑定

我有以下问题:

   @Inject
   MyClass(Service service) {
      this.service = service;
   }

   public void doSomething() {
      service.invokeSelf(); 
   }

我有一个模块

bind(service).annotatedWith(Names.named("serviceA").to(ServiceAImpl.class);
bind(service).annotatedWith(Names.named("serviceB").to(ServiceBImpl.class);

现在我的问题是我想允许用户通过命令行参数在运行时动态选择注入

public static void Main(String args[]) {
   String option = args[0];
   ..... 
}

我怎么能这样做?我是否必须创建多个模块才能做到这一点


共 (3) 个答案

  1. # 1 楼答案

    @ColinD有一个很好的方法。我可以建议

    public static void main(String[] args) {
      Module m = "serviceA".equals(args[0]) ? new AServiceModule() : new BServiceModule();
      Injector injector = Guice.createInjector(m);
      // ...
    }
    

    基本的想法(在两个答案中)是,如果您可以在喷油器制造之前做出选择,您应该始终选择这样做

    作为一种风格,我喜欢将模块内部的逻辑量保持在最低限度;但同样,这只是一个风格问题

  2. # 2 楼答案

    我认为你真正想做的是这样的:

    public class ServiceModule extends AbstractModule {
      private final String option;
    
      public ServiceModule(String option) {
        this.option = option;
      }
    
      @Override protected void configure() {
        // or use a Map, or whatever
        Class<? extends Service> serviceType = option.equals("serviceA") ?
            ServiceAImpl.class : ServiceBImpl.class;
        bind(Service.class).to(serviceType);
      }
    }
    
    public static void main(String[] args) {
      Injector injector = Guice.createInjector(new ServiceModule(args[0]));
      // ...
    }
    
  3. # 3 楼答案

    如果您需要在运行时重复选择使用mapbinder的实现是非常合适的

    您的配置如下所示:

    @Override
    protected void configure() {
      MapBinder<String, Service> mapBinder = MapBinder.newMapBinder(binder(), String.class, Service.class);
      mapBinder.addBinding("serviceA").to(ServiceAImpl.class);
      mapBinder.addBinding("serviceB").to(ServiceBImpl.class);
    }
    

    然后,在您的代码中,只需插入地图并根据您的选择获得正确的服务:

    @Inject Map<String, Service> services;
    
    public void doSomething(String selection) {
      Service service = services.get(selection);
      // do something with the service
    }
    

    您甚至可以使用custom scopes使用所选服务填充注入器