使用Guice的模块化Java插件系统

使用Guice的模块化Java插件系统,java,dependency-injection,guice,Java,Dependency Injection,Guice,我们有一组接口,例如BookingInterface、InvoiceInterface、PaymentInterface,它们由不同的业务流程实现 e、 g 我们正在考虑使每个业务流程成为一个插件,以实现公开的接口集 在我们的RESTAPI中,我们希望将一个特定的插件接口注入到我们的服务中 e、 g @Inject 公共计费服务(配置, 事件调度器事件调度器, 映射正确的接口(实现){ } 我正在查找MapBindings、AssistedInjection和FactoryModuleBuil

我们有一组接口,例如BookingInterface、InvoiceInterface、PaymentInterface,它们由不同的业务流程实现

e、 g

我们正在考虑使每个业务流程成为一个插件,以实现公开的接口集

在我们的RESTAPI中,我们希望将一个特定的插件接口注入到我们的服务中

e、 g

@Inject
公共计费服务(配置,
事件调度器事件调度器,
映射正确的接口(实现){
}

我正在查找MapBindings、AssistedInjection和FactoryModuleBuilder,但不确定如何获得正确的GUI设置,以便在运行时注入所需的插件接口。

(作为功能之一)是插件式接口的正确要求。FactoryModuleBuilder是辅助注入的一个实现细节,它只是将显式构造函数参数与Guice提供的构造函数参数混合的一种方法。如果你不需要这样做,那么你就不需要辅助注射

您仍然需要在模块中设置这些绑定:

public Business1Module extends AbstractModule {
  @Override public void configure() {
    MapBinder<String, BookingInterface> bookingBinder =
        MapBinder.newMapBinder(binder(), String.class, BookingInterface.class);
    bookingBinder.addBinding("business1").to(Business1BookingInterface.class);
    MapBinder<String, InvoiceInterface> invoiceBinder =
        MapBinder.newMapBinder(binder(), String.class, InvoiceInterface.class);
    invoiceBinder.addBinding("business1").to(Business1InvoiceInterface.class);
  }
}
结果是,您不需要自己聚合这些依赖项,Guice也不会抱怨到
Map
Map
(等)的多个冲突绑定。它们将自动组合成一个大映射

其他说明:

  • 多绑定在一个单独的JAR中,所以别忘了在类路径上安装它

  • 这可能是一个很好的理由使用:


  • 我可以将提供程序与多重绑定一起使用吗?为了避免循环依赖关系,我使用提供者映射invoiceMap注入了服务,一切正常。不再有循环依赖关系。
     @Inject
    public BillingService(Configuration configuration,
                          EventDispatcher eventDispatcher,
                          Map<String,PluginInterface> theCorrectInterfaceImplementation) {
    
    public Business1Module extends AbstractModule {
      @Override public void configure() {
        MapBinder<String, BookingInterface> bookingBinder =
            MapBinder.newMapBinder(binder(), String.class, BookingInterface.class);
        bookingBinder.addBinding("business1").to(Business1BookingInterface.class);
        MapBinder<String, InvoiceInterface> invoiceBinder =
            MapBinder.newMapBinder(binder(), String.class, InvoiceInterface.class);
        invoiceBinder.addBinding("business1").to(Business1InvoiceInterface.class);
      }
    }
    
    Injector yourInjector = Guice.createInjector(/*...*/,
        new Business1Module(), new Business2Module());
    
    Injector yourInjector = Guice.createInjector(/*...*/,
    new BusinessModule("business1",
        Business1BookingInterface.class, Business1InvoiceInterface.class),
    new BusinessModule("business2",
        Business2BookingInterface.class, Business2InvoiceInterface.class));