2012-04-12 65 views
3

說,我們有下面的代碼:吉斯如何表現不同注射類型改變

public interface Rock { 
    // Minerals are a concrete class; omitted for brevity 
    public Minerals getMinerals(); 
} 

public class Granite implements Rock { 
    // @Inject #1 - field 
    private Minerals minerals; 

    // @Inject #2 - constructor 
    public Granite(Minerals mins) { 
     super(); 
     setMinerals(mins); 
    } 

    public Minerals getMinerals() { 
     return minerals; 
    } 

    // @Inject #3 - setter 
    public void setMinerals(Minerals mins) { 
     minerals = mins 
    } 
} 

public class RockModule extends AbstractModule { 
    public void configure(Binder guiceBinder) { 
     Minerals m = new Minerals(true, 3, MineralEnum.Sedimentary); 

     guiceBinder.bind(Minerals.class).toInstance(m); 
     guiceBinder.bind(Rock.class).to(Granite.class); 
    } 
} 

public class TestInjections { 
    public static void main(String[] args) { 
     RockModule mod = new RockModule(); 
     Injector injector = Guice.createInjector(mod); 

     Granite gran = injector.getInstance(Granite.class); 
    } 
} 

我已經註釋掉3個@Inject註解他們是這裏的變量 - 我想知道吉斯將如何表現在所有3例(現場,構造或二級注射)。

  • Granite實例總是Minerals實例注入的模塊中配置?注入類型(3箇中的每一個)如何影響注入器返回的實例 - 或者它們都是相同的?
  • 如果我從來沒有明確約束模塊中的MineralsMinerals沒有定義公共的無參數構造函數?對於所有三種注射情況下,如何吉斯實例化一個Minerals實例請求Granite對象返回?

回答

3
  1. Minerals總是會注入Granite,無論您選擇何種注射技術,但一些注射是「乾淨」比其他人 - 例如,選項1讓你在注射是如何完成的控制較少,而選項3意味着你的類不能是不可變的。
  2. 如果Minerals未綁定,缺少公共無參數構造函數,並且缺少構造函數@Inject,則Guice拋出異常,除非使用@Inject(optional = true)
+0

如何字段級注入限制我/給我更少的控制(例如)?另外,如果我只用'@ Inject'註釋setter,然後使用注入器創建'Granite'實例?如果從不調用setter,Guice如何知道將'Minerals'實例(在模塊中定義)映射到這個'Granite'實例? – IAmYourFaja 2012-04-12 18:30:06

+0

1.如果你不想直接使用注入的對象作爲一個領域,但你想換行,或將其傳遞給方法或其他領域?只有構造函數和setter注入才能做到這一點。 2.吉斯掃描您的'@ Inject' setter方法時,它獲取該對象類,並調用它們,所以即使你沒有看到調用,二傳手不會被調用。 – 2012-04-12 19:13:33

+0

所以,它聽起來就像字段級注入鬆散視爲「邪惡除少數例外」,和setter級注入限制你的聲明是'final'(不變)特性的能力。聽起來建設者級別的注入是首選的方式,至少對於Guice新手來說。這些公平的陳述?並感謝迄今爲止所有的幫助! – IAmYourFaja 2012-04-12 19:20:04