2013-02-08 89 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