【问题标题】:Guice @annotations approach similar to Guice MapBinder approachGuice @annotations 方法类似于 Guice MapBinder 方法
【发布时间】:2017-03-13 02:24:38
【问题描述】:

我是 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 不能接受参数,在这种情况下覆盖@Inject 会有所帮助吗?如果是这样,我们该怎么做?

或者这种情况只能通过使用 MapBinder 绑定来实现(我不想使用 binder 的原因是我们想显式定义键值对的绑定映射,但使用注释只是简单地注释带参数的实现类 - 更易于维护)。

提前致谢。

【问题讨论】:

  • 嗨 - 我相信你会为此使用命名绑定。让类 a 做@Inject@Named("one") 然后将你的注入类绑定到“一”或“二”

标签: java dependency-injection annotations guice guice-3


【解决方案1】:

为了回答您的后续问题,我相信您正在寻找的是命名注入。看这个例子:

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

希望对你有帮助,

阿图尔

【讨论】:

    【解决方案2】:

    来自 JLS,§9.6,

    "由于 AnnotationTypeDeclaration 语法,注解类型声明不能是泛型的,并且不允许使用 extends 子句。

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

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

    【讨论】:

    • 非常感谢。这有帮助。那么是否有任何通过 Guice @annotations 替代 MapBinder 的方法?
    猜你喜欢
    • 1970-01-01
    • 2014-02-22
    • 2015-03-27
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 1970-01-01
    相关资源
    最近更新 更多