1. ホーム

[解決済み】フィールド・インジェクションとは何ですか、またそれを回避する方法は?

2022-04-04 07:40:23

質問

Spring MVC とポートレットに関するいくつかの記事で、次のように書かれています。 フィールドインジェクション は推奨されません。私の理解では フィールドインジェクション でBeanをインジェクトした場合です。 @Autowired このように

@Component
public class MyComponent {
    @Autowired
    private Cart cart;
}

また、研究中、私は コンストラクタ注入 :

@Component
public class MyComponent {
    private final Cart cart;

    @Autowired
    public MyComponent(Cart cart){
       this.cart = cart;
    }
}

この2種類の注射のメリットとデメリットは何ですか?


EDIT 1: この質問は、次の質問と重複しています。 この質問 確認しました。質問にも回答にもコード例がないので、私が使っているインジェクションタイプの推測が正しいかどうかは不明です。

どのように解決するのですか?

インジェクションの種類

依存関係をビーンに注入する方法として、3つのオプションがあります。

  1. コンストラクタを使用する
  2. セッターや他のメソッドを介して
  3. リフレクションにより、フィールドに直接入力する

あなたはオプション3を使用しています。を使用すると、そのようなことが起こります。 @Autowired を直接フィールドに貼り付けてください。


インジェクションのガイドライン

一般的なガイドラインです。 Springが推奨する (のセクションを参照してください)。 コンストラクタベースのDI または セッターベースDI )は以下の通りです。

  • 必須の依存関係や不変性を目指す場合は、コンストラクタ注入を使用します。
  • オプションまたは変更可能な依存関係には、セッターインジェクションを使用します。
  • ほとんどの場合、フィールドインジェクションは避けてください

フィールドインジェクションの欠点

フィールドインジェクションが嫌われる理由は、以下の通りです。

  • コンストラクタ注入のように、イミュータブルオブジェクトを作成することはできません。
  • クラスはDIコンテナと緊密に結合しており、DIコンテナの外では使用できない。
  • クラスはリフレクションなしでは(ユニットテストなどで)インスタンス化できない。インスタンス化するためにDIコンテナが必要で、テストは統合テストに近くなります。
  • 実際の依存関係は外から見えないようになっており、インターフェイス(コンストラクタやメソッド)には反映されません。
  • 10個のような依存関係を持つことは本当に簡単です。コンストラクタ注入を使用している場合、10個の引数を持つコンストラクタが存在することになり、何か怪しいというシグナルが発せられるでしょう。しかし、フィールドインジェクションを使えば、注入されたフィールドを無限に追加することができます。依存関係が多すぎるということは、そのクラスが通常複数のことを行っていて、単一責任原則に違反している可能性があるという赤信号です。

結論

ニーズに応じて、コンストラクタ注入を主に使用するか、コンストラクタとセッタの注入をいくつか組み合わせて使用する必要があります。フィールドインジェクションには多くの欠点があるため、避けるべきでしょう。フィールドインジェクションの唯一の長所は、より便利に書けることですが、それはすべての短所を上回るものではありません。


その他の資料

フィールドインジェクションが通常推奨されない理由について、ブログ記事を書きました。 フィールド依存性注入は有害であると考えられている .