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”的子类。
谢谢!
如标题中所示,您的问题有一个更简单的解决方案:如果您想要任意数量的MyClass或MyDependency实例,则可以注入Provider<MyClass>或Provider<MyDependency>。无论您是否实际上已在模块中绑定提供者,这都是事实。对于图中任何可用的T,Guice可以实际注入T或Provider<T>。(这些分别对应于Injector.getInstance和Injector.getProvider。)
就像问题的主体一样,有两部分:Key为同一个对象创建多个注入对象Class,并使用不同的名称和注入的依赖关系以所需的方式设置实例。
Guice使用来标识绑定Key,,这是完全合格的类(如MyClass或List<MyClass>),并带有可选的“绑定注释”。这是一个本身用BindingAnnotation或注释的注释javax.inject.Qualifier。您可以创建自己@Named的字符串,也可以使用带有String 的内置调用(因此@Named("foo")与有所不同@Named("bar"))。
大多数情况下,无需直接使用Key就可以实现:annotatedWith在bind调用中使用或将注释添加到@Provides方法上,然后通过将注释放在构造函数参数或@Inject注释字段上来请求它们。但是,您仍然可以使用Key上的静态方法,getInstance并getProvider通过手动创建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.Factory和myClassFactory.create("foo"),可以直接在使用的类中或使用@Provides上面的技术来进行操作。详细信息超出了问题的范围,但请查阅“辅助注入”以获取有关语法和添加适当的JAR的详细信息。