2012-04-13 6 views
12

のGuiceの私の理解では、ということです:Guiceの:フィールドインジェクションの意味合い

  • コンストラクタレベル注入(@Inject public class Widget(Dep one, Dep two)はGuiceのは、常にそれがInjectorを通じて呼び出されるたびにそのコンストラクタを注入します意味。そして
  • メソッドレベルの注射(@Inject public void setDepOne(Dep one)はGuiceのはいつも長いWidgetオブジェクトはGuiceのInjector

を使用して作成されたように、これら2つの仮定が正しいされており、それが呼び出されるたびに、その方法を注入するを意味しますか?そうでない場合は、明確にしてください!

だから私が悩んでいるのは、フィールドレベル注入の意味は何ですか?

@Inject private Dep one; 

これは、オブジェクトがGuiceのインジェクタを介して作成されたときのGuiceは常にプロパティを注入することを意味していますか?その場合、私はコンストラクタレベルの注入と衝突すると思います。例えば

は、競合/エラー、次の原因を行います。事前に

public class Widget { 
    @Inject private Dep one; 

    private Dep two; 

    // Dep one already injected as a field! 
    @Inject public Widget(Dep one, Dep two) { 
     // ... 
    } 
} 

感謝を!

答えて

0

あなたの前提は正しいです。この特定のケースでGuiceは、同じフィールドに行くことがわからないので、何も他のものがなければ、oneを2度(コンストラクタを通して1度、フィールドを介して)2回注入します。

19

Guiceは、すべてのフィールド、メソッド、および@Injectで注釈が付けられた単一のコンストラクタを常に注入します。コンストラクタが常に最初に注入されるので、注釈付きフィールドは実際にその注入を上書きすることに注意してください。この変形例を取る:

[email protected] 
[email protected] 

明らかに2つの異なるオブジェクト:実行すると、これはこのような何かを生成します

class Widget { 
    @Inject 
    private Dep one; 

    @Inject 
    public Widget(Dep one) { 
     this.one = one; 
     System.out.println(one); 
    } 

    public void printDependency() { 
     System.out.println(one); 
    } 
} 

class Dep {} 

public class MyMain { 
    public static void main(String[] args) { 
     Injector i = Guice.createInjector(); 
     i.getInstance(Widget.class).printDependency(); 

    } 
} 

。最初の行はコンストラクタです。 2番目はフィールド注入です。

Guiceコードサンプルを書くときに冗長性を減らすことを除いて、私はしばしばフィールドインジェクションの使用を発見していません。プロダクションコードでは、コードをテストするのが難しくなるため、賢明ではありません。

+0

Guiceは、シングルトンなどの他のバインディングが見つからない限り、それが挿入するすべての依存関係の新しいインスタンスを常に作成します。 – logan

+0

なぜテストにうまくいかないのか説明できますか? – suitianshi

+0

この場合、注入されたフィールドはプライベートなので、リフレクションのようなものを使わずにアクセスするのが難しくなります。 –