【问题标题】:Create multiple instances of the same class with Guice使用 Guice 创建同一类的多个实例
【发布时间】:2017-02-19 00:10:55
【问题描述】:

对不起,如果这是一个微不足道的问题,我是 Guice 的新手。 假设我有以下课程:

public class MyClass {
     @Inject
     public MyClass(final MyDependency myDependency) {
          this.name = myDependency.getName();
     }

     public String getName() {
          this.name;
     }
}

然后我想做的其他地方:

public class SomeOtherClass {
    public void test() {
        MyClass instanceFoo = injector.getInstance(MyClass.class);
        MyClass instanceBar = injector.getInstance(MyClass.class);

        assertTrue("foo", instanceFoo.getName());
        assertTrue("bar", instanceBar.getName());
    }
}

我想要两个“MyClass”实例,一个名称为“foo”,一个名称为“bar”(即它们每个都有不同的依赖实例)。如何将这 2 个实例添加到我的注入器中,以及如何使用“injector.getInstance”检索它们中的每一个?

我不想为每个可能的依赖项创建“MyClass”的子类。

谢谢!

【问题讨论】:

    标签: java dependency-injection guice


    【解决方案1】:

    如标题所示,您的问题有一个更简单的解决方案:如果您想要任意数量的 MyClass 或 MyDependency 实例,您可以注入 Provider<MyClass>Provider<MyDependency>。无论您是否在模块中实际绑定了提供程序,这都是正确的;对于图中可用的任何 T,Guice 实际上可以注入 TProvider<T>。 (这些分别对应Injector.getInstanceInjector.getProvider。)

    与问题的正文一样,有两部分:为同一个Class 制作多个可注入的Key,并使用不同的名称和注入的依赖项以您想要的方式设置实例。

    键和绑定注释

    Guice 使用Key 标识绑定,这是一个完全限定的类(如MyClassList<MyClass>)结合可选的“绑定注释”。这是一个注解,它本身带有BindingAnnotationjavax.inject.Qualifier 的注解;你可以创建自己的,或者使用内置的 @Named 接受一个字符串(所以 @Named("foo")@Named("bar") 不同)。

    大多数情况下,您可以不直接使用 Key:在您的 bind 调用中使用 annotatedWith 或将注解添加到 @Provides 方法中,并通过将注解添加到构造函数参数或 @Inject 来请求它们-带注释的字段。但是,您仍然可以通过手动创建 Key,使用 Key 上的静态方法来使用 getInstancegetProvider。 (对于复杂的情况,请使用 TypeLiteral 或 Names.named;有关详细信息,请参阅他们的文档。)

    设置实例

    既然您知道如何注入@Named("foo") MyClass@Foo MyClass,您如何提供它们?根据您的需要,我会选择以下三个选项之一:绑定toInstance、使用@Provides 方法或创建“辅助注入”工厂。

    • 如果您的 MyClass 实例本身不需要注入,并且您不改变或操纵实例状态,您可以根据需要准备实例,然后使用 bindtoInstancebind

    • 您还可以编写一个@Provides @Named("foo") MyClass 方法,该方法采用MyClass 参数(Guice 通过注入器提供)、设置名称并返回实例。这是编写 Provider 类或实例的一种低开销替代方法,它会为您提供一个新实例,而不是 toInstance 绑定所暗示的共享。

    • 1234563 Guice 注射器。这将允许您注入MyClass.Factory 并调用myClassFactory.create("foo"),您可以直接在您的消费类中执行此操作,或者使用上面的@Provides 技术。细节有点超出问题的范围,但请查看“辅助注入”以获取有关语法和添加适当 JAR 的详细信息。

    【讨论】:

      猜你喜欢
      • 2013-06-02
      • 2019-04-02
      • 2014-06-28
      • 1970-01-01
      • 2011-06-17
      • 2016-04-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-20
      相关资源
      最近更新 更多