我是Guice DI的新手。我想澄清我的情景。
简单来说,是否通过Guice @annotations替换了MapBinder?
我的情景:
Interface A{}
Class A1 implements A{}
Class A2 implements A{}
我想按如下方式注入A的实现类,
if(param = One) then Inject A1 to A
if(param = Two) then Inject A2 to A
据我所知,上面的内容可以用MapBinder完成,但我想通过以下注释来完成,
Class A1 implements A
{
@Inject(param = One)
A1(){}
}
Class A2 implements A
{
@Inject(param = Two)
A2(){}
}
因此,使用params注释类可以根据参数(一个或两个)自动选择和注入类。
由于@Inject不能接受params,覆盖@Inject会有助于这种情况吗?如果是的话,我们该怎么做?
或者这种情况是否只能通过使用MapBinder进行绑定来实现(我不想使用binder的原因是我们想要明确定义键值对的绑定映射,但只是简单地使用注释用params注释实现类 - 更容易维护。
提前致谢。
答案 0 :(得分:3)
来自JLS,§9.6,
“凭借AnnotationTypeDeclaration语法,注释类型声明不能是通用的,也不允许使用extends子句。
“注释类型无法显式声明超类或超接口这一事实的结果是注释类型的子类或子接口本身永远不是注释类型。同样,java.lang.annotation.Annotation本身不是注释类型。“
所以,不,“覆盖[原文如此]”没有用,因为没有扩展类型可以作为注释类型。
答案 1 :(得分:3)
要回答你的后续问题,我相信你所寻找的是名为注射剂。见这个例子:
public class GuiceNamedTest extends AbstractModule {
public static void main(String[] args) {
Injector i = Guice.createInjector(new GuiceNamedTest());
i.getInstance(InstaceOne.class);
i.getInstance(InstaceTwo.class);
}
@Override
protected void configure() {
Bean beanOne = new Bean();
beanOne.name = "beanOne";
Bean beanTwo = new Bean();
beanTwo.name = "beanTwo";
bind(Bean.class).annotatedWith(Names.named("one")).toInstance(beanOne);
bind(Bean.class).annotatedWith(Names.named("two")).toInstance(beanTwo);
bind(InstaceOne.class);
bind(InstaceTwo.class);
}
public static class Bean {
String name;
}
public static interface A {}
public static class InstaceOne implements A {
@javax.inject.Inject
public InstaceOne(@Named("one") Bean b1) {
System.out.println(b1.name);
}
}
public static class InstaceTwo implements A {
@javax.inject.Inject
public InstaceTwo(@Named("two") Bean b1) {
System.out.println(b1.name);
}
}
}
在这里,我使用annotatedWith
来命名我的guice处理的实例。其中一个对应于String" one"和另一个"两个",类似于你的例子。
然后,我可以在A
的实现中使用@Named
注释对这些bean进行特定注入。
运行以上代码时的结果是:
beanOne
beanTwo
正如您所看到的,它将正确的bean实例注入正确的实现中。
希望有所帮助,
Artur