如何通过 Guice 注入 3 个具有不同依赖性的相同类型的实例?

How inject 3 instances of same type with different dependence by Guice?

我正在使用 Guice 来管理我的 class 依赖。我有一个 LogicHandler class 依赖于几个组件 class.

  public interface LogicHandler {
      private Component component1;
      private Component component2;
      private Component component3;
  }

  public interface Component {
      public String doWork();
  }

我将有 3 个 LoigcHanlder 实例。使用哪个实例将在 运行 时间内决定。每个实例都有不同的组件实现,所有实现都是预定义的。

如果我使用 spring DI,xml 配置将如下所示:

<bean id="handler1" class="org.sample.handlers.DefaultHanlder">
  <property name="component1" ref="componentImplementationA" />
  <property name="component2" ref="componentImplementationB" />
  <property name="component3" ref="componentImplementationC" />
</bean>

<bean id="handler2" class="org.sample.handlers.DefaultHanlder">
  <property name="component1" ref="componentImplementationD" />
  <property name="component2" ref="componentImplementationE" />
  <property name="component3" ref="componentImplementationF" />
</bean>

<bean id="handler3" class="org.sample.handlers.DefaultHanlder">
  <property name="component1" ref="componentImplementationG" />
  <property name="component2" ref="componentImplementationH" />
  <property name="component3" ref="componentImplementationI" />
</bean>

注意:所有处理程序均由 DefaultHanlder 实现。

Using which handler instance based on some parameters.

使用限定符(例如@Named("handler1"))并显式绑定您的实例。

 bind(Component.class).annotatedWith(Names.named("handler1").toInstance(...);

假设我正确理解了你的问题,你想选择一个特定的具体实现来基于特定的参数进行绑定。一种方法是创建一个模块,将决定绑定哪个模块所需的参数作为构造函数。绑定特定具体实现的逻辑将在模块的 bind 方法中。例如

public class YourModule extends AbstractModule {

Parameters settings;

public YourModule(Parameters settings) {
    this.settings = settings;
}

@Override
protected void configure() {
   if(settings.val == 1) {
      bind(DefaultHanlder.class).toInstance(ComponentA.class);
   } else if(settings.val == 2) {
      bind(DefaultHanlder.class).toInstance(ComponentB.class);
   }
   .
   .
   .
}

创建喷油器时,使用 YourModule 模块以便正确接线。然后注入器应该为 DefaultHanlder 注入正确的具体 class 而你的客户端代码不知道如何选择正确的具体实现。

可能还有其他方法可以做到这一点(例如,AssistedInjection 也可能有效)但使用单独的模块非常简单。