本文へスキップ
BecomeCoder

Spring / Spring Bootコース · 第1章 Springとは ― なぜ世界中で使われるのか · レッスン2

依存性注入(DI)― Springの心臓部

ローカル実施

導入

Springを一言で表すなら「DIコンテナ」です。デザインパターンコースで触れた「抽象に依存させ、具体を外から注入する」——あの考え方を、フレームワークの機能として提供するのがSpringの本質です。

説明

DI(Dependency Injection: 依存性注入) とは、あるオブジェクトが必要とする別のオブジェクト(依存)を、自分で作らず、外から渡してもらう 仕組みです。

まず、DIを使わない場合を見てみましょう。

class OrderService {
    // 自分で new している = MailNotifier に固定され、差し替えられない
    private MailNotifier notifier = new MailNotifier();

    public void complete() {
        notifier.notify("ご注文が完了しました");
    }
}

これを、Springの流儀に書き換えます。

@Service
class OrderService {
    private final Notifier notifier;

    // コンストラクタで「必要なもの」を受け取るだけ。誰が渡すかは気にしない
    public OrderService(Notifier notifier) {
        this.notifier = notifier;
    }

    public void complete() {
        notifier.notify("ご注文が完了しました");
    }
}

OrderService は「Notifier が必要だ」と宣言するだけで、自分ではインスタンスを作りません。では誰が Notifier を渡すのか——それが Springの DIコンテナ です。

graph TD
  C["DIコンテナ<br/>(ApplicationContext)"] -->|生成して保持| N["MailNotifier のインスタンス"]
  C -->|生成して保持| O["OrderService のインスタンス"]
  N -.->|注入(コンストラクタで渡す)| O

Springは起動時に、@Service などの目印がついたクラスを見つけてインスタンス化し(このインスタンスを Bean と呼びます)、必要な依存を自動で注入して、オブジェクトの「配線」を組み立ててくれます。

このDIの何がうれしいのか。

  1. 差し替えが容易Notifier の実装をメールからSlackに変えても、OrderService は1行も変えなくていい。
  2. テストしやすい … テスト時は本物の代わりに「偽物(モック)」の Notifier を注入できる。
  3. 依存関係が一望できる … 各クラスが「何を必要とするか」がコンストラクタに明示される。

次章から、この Bean と DIコンテナの具体的な使い方に入っていきます。SpringはこのDIを土台に、Web・データベース・セキュリティといった機能を積み上げているのだ、という全体像をここでつかんでおいてください。