Guice @annotations 方法类似于 Guice MapBinder 方法

Guice @annotations approach similar to Guice MapBinder approach

我是 Guice DI 的新手。我想弄清楚我的情况。

简单的说,有没有通过Guice @annotations来替代MapBinder的?

我的场景:

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

我想按如下方式注入 A 的实现 class,

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(){}    
}

所以让class注解params可以根据参数(一或二)自动选择和注入class。

既然@Inject 不能接受参数,覆盖@Inject 在这种情况下会有帮助吗?如果可以,我们该怎么做?

或者这种情况是否只能通过使用MapBinder进行绑定来实现(我不想使用binder的原因是我们想明确定义键值对的绑定映射,而只是简单地使用注释用参数注释实现 class - 更容易维护)。

提前致谢。

来自 JLS,§9.6,

"根据 AnnotationTypeDeclaration 语法,注释类型声明不能是通用的,并且不允许有扩展子句。

"A consequence of the fact that an annotation type cannot explicitly declare a superclass or superinterface is that a subclass or subinterface of an annotation type is never itself an annotation type. Similarly, java.lang.annotation.Annotation is not itself an annotation type."

所以,不,"overriding [sic]" 没有帮助,因为扩展类型不能是注解类型。

为了回答你的后续问题,我相信你正在寻找的是命名注入。请参阅此示例:

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 的正确实例注入到正确的实现中。

希望对您有所帮助,

阿图尔