2013-02-08 88 views
5

我有一个简单的POJO:注入命名吉斯单

public class MyPOJO { 
    @Inject 
    private Fizz fizz; 

    private Buzz buzz; 

    // rest of class omitted for brevity 
} 

我想配置我吉斯模块,有两种类型的Fizz ES,这注入:

  1. 一个特殊的, global-singleton Fizz instance;和
  2. 其他(非特殊)Fizz实例

我想MyPOJO与特殊/单实例注入。所以,我修改了代码:

public class MyPOJO { 
    @Inject @Named("Special-Fizz") 
    private Fizz fizz; 

    private Buzz buzz; 

    // rest of class omitted for brevity 
} 

然后我的模块中:

public class MyModule extends AbstractModule { 
    @Override 
    public void configure() { 
     bind(Fizz.class).annotatedWith(
      Names.named("Special-Fizz")) 
      .to(Fizz.class); 

     // Other bindings here... 
    } 

    @Provides @Singleton 
    private Fizz providesFizz() { 
     return new Fizz(true, "Special", 12.0); 
    } 
} 

但是,当我试图单元测试(JUnit的4.10)这样的:

public class MyTest { 
    @Named("Special-Fizz") private Fizz specialFizz; 

    @Test 
    public void usingNamedShouldInjectSpecialFizz() { 
     MyModule mod = new MyModule(); 
     Injector injector = Guice.createInjector(mod); 

     specialFizz = injector.getInstance(Fizz.class); 

     Assert.assertTrue(specialFizz != null); 
    } 
} 

此通过。到现在为止还挺好。不过,如果我改变specialFizz字段的名称:

@Named("Special-Fuzz-This-Shouldnt-Work") private Fizz specialFizz; 

,并重新运行测试,它仍然通过。为什么?!?我在哪里误入歧途?提前致谢。

回答

3

很奇怪。 Guice应该抱怨,如果它找不到注入的Named绑定。不过,我有点困惑于你的测试。我不知道injector.inject是做什么的。你的意思是injectMembers?实际获得POJO的实例并确保它按照您期望的方式工作可能更有意义。也许类似于:

public class FizzTest { 

    public static class MyModule extends AbstractModule { 
    @Override 
    protected void configure() { 
    } 

    @Provides 
    @Singleton 
    @Named("Special-Fizz") 
    public Fizz providesFizz() { 
     return new Fizz(true); 
    } 
    } 

    public static class Fizz { 
    boolean special = false; 
    public Fizz() {} 
    public Fizz(boolean special) { 
     this.special = special; 
    } 
    } 

    public static class MyPOJO { 
    @Inject @Named("Special-Fizz") 
    private Fizz fizz; 

    @Inject 
    private Fizz otherFizz; 
    } 

    @Test 
    public void test() { 
    MyModule mod = new MyModule(); 
    Injector injector = Guice.createInjector(mod); 

    MyPOJO pojo = injector.getInstance(MyPOJO.class); 
    assertTrue(pojo.fizz.special); 
    assertTrue(!pojo.otherFizz.special); 
    } 

} 
+0

Thanks @condit(+1) - 这是我在输入这个问题时的一个错误。我编辑了我的原始问题,以表明我实际上调用了'injector.getInstance',而不是'injector.inject'。这会为你改变什么吗? 'getInstance'不正确,我在这里使用?如果是这样,为什么,什么是?再次感谢! – IAmYourFaja 2013-02-09 02:03:56

+0

在你测试你问喷射器Fizz'的'一个实例,它始终能为您提供(因为你'@ Provides'方法)。我想你想得到一个'MyPOJO'的实例。请注意,你得到的'Fizz'与测试中的'Fizz'成员无关。所以在这种情况下更改'@ Named'将不起作用。 – condit 2013-02-09 02:05:50

+0

你钉了它。我只是要求它注入一个'MyPOJO',并且正确地向它的'Fizz'属性注入了特殊的嘶嘶声。神秘解决 - 只是一个执行不力的测试方法。再次感谢! – IAmYourFaja 2013-02-09 02:09:07

2

Guice看到@Provides方法,并愉快地使用它来注入Fizz。如果你想拥有的Fizz一个特例,您可以从providesFizz()方法删除注释,而是与

bind(Fizz.class) 
    .annotatedWith(Names.named("Special-Fizz") 
    .toInstance(providesFizz()); 

这样绑定,你告诉吉斯正好为“特殊菲斯”使用的Fizz,同时仍然让它注入Fizz否则“正常”。

声明:我没有真正尝试像你这样的设置,但我使用了一个类似的设置。让我知道它是否有效。

+0

Thanks @Bradley T. Hughes(+1) - **然而**您的建议不会改变任何内容。单元测试仍然通过,不管你命名'Fizz'。你提到了一些我认为很有趣的东西。你说过“*我实际上没有尝试像你这样的设置......”,但是,从你的回答中我推断出你使用Guice似乎很舒服。所以这让我想知道:*这是一个奇怪的设置,我正在使用?*我认为Guice的*点*是使用Classes和Annotations一起准确地确定你想要注入什么类型/配置... – IAmYourFaja 2013-02-09 01:43:23

+0

..那么我在这里做的事与众不同?如果是这样,为什么?!?我在哪里误解Guice的正常用法?再次感谢! – IAmYourFaja 2013-02-09 01:44:07

+0

我不认为这是一个奇怪的设置。说实话,我还没有使用过Guice,所以我当然不是专家。不同的是,我正在使用的代码使用相同的注释来注入两种不同的类型(每个类型的单个实例)。 – 2013-02-09 19:38:06