1

I am new to Guice DI. And I would like to get my scenario clarified.

To put it simple, Is there any replacement of MapBinder through Guice @annotations?

My Scenario:

Interface A{}
Class A1 implements A{}
Class A2 implements A{}

I would like to Inject the implementation class of A as follows,

if(param = One) then Inject A1 to A
if(param = Two) then Inject A2 to A

I understand that the above could be done with MapBinder, but I would like to do it through annotations as follows,

Class A1 implements A
{     
@Inject(param = One)     
A1(){}    
}

Class A2 implements A
{     
@Inject(param = Two)     
A2(){}    
}

So making the class annotated with params could automatically picks and inject the class based on the parameter (One or Two).

Since @Inject cannot accept params, overriding @Inject would help in this scenario? if so, how do we do so?

Or Is this scenario could only be achieved through binding using MapBinder (The reason why I wouldn't want to use binder is that we would want to define the binding map of key value pair explicitly, but using annotations just simply annotate the implementation class with params - easier maintenance).

Thanks in advance.

4

2 回答 2

3

从 JLS,§9.6,

“凭借 AnnotationTypeDeclaration 语法,注释类型声明不能是通用的,并且不允许使用 extends 子句。

“注释类型不能显式声明超类或超接口这一事实的结果是,注释类型的子类或子接口本身绝不是注释类型。同样,java.lang.annotation.Annotation 本身也不是注释类型。 "

所以,不,“覆盖 [原文]”不会有帮助,因为没有扩展类型可以是注释类型。

于 2017-03-13T02:36:36.900 回答
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 处理的实例。其中一个对应于字符串“one”,另一个对应于“two”,类似于您的示例。

然后,我可以在我的实现中A使用@Named注释对这些 bean 进行特定注入。

上面代码运行的结果是:

beanOne
beanTwo

如您所见,它将我的 bean 的正确实例注入到正确的实现中。

希望有帮助,

阿图尔

于 2017-03-15T15:01:31.767 回答