【Spring解体新書 バッチ編】1.1 SpringのDIについて

Springを使った開発では、DIについての知識が必須となります。

DI(Dependency Injection, 依存性の注入)とは、インスタンスを変数に代入することです。例えば、以下のようにListインターフェースのフィールドにArrayListクラスのインスタンスを代入します。

public class Hoge {

  // フィールド
  private List<Sample> sampleList = new ArrayList<>();

  ・・・
} 

Listインターフェースを使用しているため、クラスをLinkedListに変更することも可能です。ArrayListとLinkedListのどちらを使っても、メソッドは同じ値を返します。しかし、処理に得意・不得意があるため性能に差が出ます。

クラスから他のクラスを使用することを依存といいます。

SpringのDIでは、インスタンスを自動で代入してくれます。Sampleインターフェースにインスタンスを代入する場合、以下のようなコードを書きます。

@Component
public class SampleImpl implements Sample {
  ・・・
}

まずは、クラスに@Componentなどのアノテーションを付けます。これでDIコンテナという入れ物にBeanとして登録されます。Beanとは、SpringがDI対象として管理するクラスのことです。

そして、このクラスのインスタンスを代入するために、以下のようなコードを書きます。

@Component
public class Hoge {

  // フィールドに代入
  @Autowired
  private Sample sample;

・・・
}

@Autowiredアノテーションを付けられるのは、以下の3か所です。

  • フィールド

  • コンストラクタ

  • setter

@Autowiredアノテーションを付けると、以下のようなインスタンスを代入すると思ってください。

public class Hoge {

  // DIコンテナからインスタンスを取得するようなイメージ
  private Sample sample = DIContainer.getSample();

  ・・・
}

なぜ直接インスタンスを代入しないのでしょうか?それは、後から代入するクラスを変更できるからです。例えば、ローカル環境と本番環境で使用するクラスを変更したい場合があります。ローカル環境ではテスト用のクラス(スタブ)を使い、本番環境では別のクラスを使用することができます。

そして、DIコンテナではインスタンスを管理しています。

デフォルトでは、システムの起動時にインスタンスを1つだけ生成します。そして、そのインスタンスを使いまわします。これをsingletonといいます。

インスタンスを生成・破棄するタイミングをスコープといいます。スコープを変更するためには、以下のようなコードを書きます。

@Component
@Scope("prototype")
public class SmapleImpl implements Sample {
  ・・・
}

@Scopeアノテーションを付けると、スコープを変更できます。prototypeでは、新しいインスタンスを毎回生成します。

他にも、Web開発特有のスコープもあります。Springバッチ特有のスコープもありますが、それは後の章で説明します。

簡単にまとめると、SpringのDIは以下のような動作をします。
@Componentなどが付いたクラスを探す→Beanとして登録→インスタンスを管理→@Autowiredが付いている箇所にインスタンスを代入

この記事が気に入ったらサポートをしてみませんか?