サービスを挿入する場合、2つの選択肢があります。
フィールド注入:
@Inject
private MyService myService;
またはコンストラクター注入:
private MyService myService;
@Inject
public ClassWhereIWantToInject(MyService mySerivce){
this.myService = myService;
}
なぜ Constructor injection
よりも良い Field injection
?
次のようなことをします(私はあなたがスプリングブートまたはあなたのCDIに匹敵するものを使用していると思います)
public class ClassWhereIWantToInject{
private MyService myService;
@Inject
public ClassWhereIWantToInject(MyService mySerivce){
this.myService = myService;
}
}
この関連 question には、フィールドによるインジェクションの代わりにコンストラクタによるインジェクションを使用する理由がいくつかあります。これは、より複雑なロジックを追加する必要なしに、CDI以外の環境、つまり単体テストでもコンストラクターによる初期化を使用できるという利点に要約されます。
私は、フィールドインジェクションの欠点を2つだけ見つけました。
オブジェクトがテスト中の場合、モックを注入するのは困難です。 (Mockitoの@InjectMocks
で解決できます)
サークルの依存関係。 Bean A
がBean B
に依存し、Bean B
がBean A
を必要とする場合。コンストラクターインジェクションがある場合は、簡単に見つけることができます。
この優れた投稿( https://blog.marcnuri.com/field-injection-is-not-recommended/ )を読むと、なぜField Injectionは良い選択ではありません。
finalキーワードを使用して、Fieldimmutableを作成することはできません。
[〜#〜] srp [〜#〜](単一の責任の原則)、このフィールドを持つクラスがサードパーティのクラスの初期化タイミングに何らかの責任を持ち始めると、.
このインジェクションを含むクラスがフレームワーク(spring/ejb/cdi)によってインジェクトされる場合、フィールドインジェクションは正しく実行されます。それ以外の場合(クラスは、new演算子を使用して呼び出し元によってインスタンス化されます)、実際にはNullPointerExceptionが発生するのを待機しています。この場合、コンストラクター注入を使用することをお勧めします。
フレームワークによって注入されたクラスで注入が行われる場合、信頼性の高いフィールド注入を実行できます。