使用Guice创建同一类的多个实例

Hen*_*rre 3 java dependency-injection guice

抱歉,这是一个琐碎的问题,我是Guice的新手。假设我有以下课程:

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

     public String getName() {
          this.name;
     }
}
Run Code Online (Sandbox Code Playgroud)

然后我想在其他地方做:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

我想有两个“ MyClass”实例,一个实例名为“ foo”,一个实例名为“ bar”(即,每个实例也具有其依赖项的不同实例)。如何将这两个实例添加到我的注射器中,如何使用“ injector.getInstance”检索它们中的每个实例?

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

谢谢!

Jef*_*ica 5

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

就像问题的主体一样,有两部分:Key为同一个对象创建多个注入对象Class,并使用不同的名称和注入的依赖关系以所需的方式设置实例。

键和绑定注释

Guice使用来标识绑定Key,,这是完全合格的类(如MyClassList<MyClass>),并带有可选的“绑定注释”。这是一个本身用BindingAnnotation或注释的注释javax.inject.Qualifier。您可以创建自己@Named的字符串,也可以使用带有String 的内置调用(因此@Named("foo")与有所不同@Named("bar"))。

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

设置实例

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

  • 如果您的MyClass实例本身不需要注入,并且您不更改或操纵实例状态,则只需准备根据需要命名的实例,然后bind使用即可toInstance

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

  • 如果您确实希望name使其成为类的构造函数参数的一部分,或者为了使实例保持不变,则可以使用“辅助注入”来告诉Guice您自己提供了哪些参数以及哪些来自Guice注入器。这将允许您注入MyClass.FactorymyClassFactory.create("foo"),可以直接在使用的类中或使用@Provides上面的技术来进行操作。详细信息超出了问题的范围,但请查阅“辅助注入”以获取有关语法和添加适当的JAR的详细信息。