web-dev-qa-db-ja.com

コンストラクターインジェクションとフィールドインジェクション

サービスを挿入する場合、2つの選択肢があります。

フィールド注入:

 @Inject 
 private MyService myService;

またはコンストラクター注入:

private MyService myService; 

@Inject
public ClassWhereIWantToInject(MyService mySerivce){
    this.myService = myService;
}

なぜ Constructor injection よりも良い Field injection

12
Riadh

次のようなことをします(私はあなたがスプリングブートまたはあなたのCDIに匹敵するものを使用していると思います)

public class ClassWhereIWantToInject{

    private MyService myService; 

    @Inject
    public ClassWhereIWantToInject(MyService mySerivce){
        this.myService = myService;
    }
}

この関連 question には、フィールドによるインジェクションの代わりにコンストラクタによるインジェクションを使用する理由がいくつかあります。これは、より複雑なロジックを追加する必要なしに、CDI以外の環境、つまり単体テストでもコンストラクターによる初期化を使用できるという利点に要約されます。

5
hecko84

私は、フィールドインジェクションの欠点を2つだけ見つけました。

  • オブジェクトがテスト中の場合、モックを注入するのは困難です。 (Mockitoの@InjectMocksで解決できます)

  • サークルの依存関係。 Bean AがBean Bに依存し、Bean BがBean Aを必要とする場合。コンストラクターインジェクションがある場合は、簡単に見つけることができます。

3
dehasi

この優れた投稿( https://blog.marcnuri.com/field-injection-is-not-recommended/ )を読むと、なぜField Injectionは良い選択ではありません。

finalキーワードを使用して、Fieldimmutableを作成することはできません。

[〜#〜] srp [〜#〜]単一の責任の原則)、このフィールドを持つクラスがサードパーティのクラスの初期化タイミングに何らかの責任を持ち始めると、.

1
PedroPK

このインジェクションを含むクラスがフレームワーク(spring/ejb/cdi)によってインジェクトされる場合、フィールドインジェクションは正しく実行されます。それ以外の場合(クラスは、new演算子を使用して呼び出し元によってインスタンス化されます)、実際にはNullPointerExceptionが発生するのを待機しています。この場合、コンストラクター注入を使用することをお勧めします。

フレームワークによって注入されたクラスで注入が行われる場合、信頼性の高いフィールド注入を実行できます。

0
Riadh