Java初心者必見!SpringのDI(依存性注入)をわかりやすく解説

Java

はじめに

JavaでSpringを利用する際に理解しておかなければならない概念にDI(依存性注入)があります。
今回はDIについて学び、より優れたアーキテクチャーを作れるようになりましょう。

DI(依存性注入)とは?

DI(Dependency Injection / 依存性注入)というのは、「必要なものを外から渡す」という考え方です。たとえば、おもちゃの車を考えてみましょう。そのおもちゃは、電池がないと動きません。でも、おもちゃ自身が電池を探してきて入れることはできませんよね?なので、電池は外から誰かが入れてあげる必要があります。

プログラムでも同じように、クラス(プログラムの部品)が動くために、他の部品が必要なことがあります。このとき、必要な部品を外から渡すことを「依存性注入(DI)」と言います。

SpringでのDI

Spring(スプリング)はプログラムを組むときに便利なお手伝いツールです。このSpringは、「このクラスにはこれが必要」という情報を元に、必要な部品(オブジェクト)を外から自動で入れてくれます。

@Autowiredとは?

@Autowiredは、「この部分に必要なものをSpringに自動で入れてね!」とお願いするマークです。
アノテーションと言います。

どうしてDIが便利なの?

おもちゃの車が「電池が必要」と教えてあげると、家族みんながどこに電池を入れれば動くのか分かりやすくなりますよね。プログラムも同じで、DIを使うとクラス同士のつながりがハッキリします。だから、部品の変更や修理がしやすく、後でプログラムを見た人にも分かりやすくなります。

例を見てみよう

電池を必要とするおもちゃの車(クラス)を作る

車が電池を必要とすることを、@Autowiredを使ってSpringに教えます。

Java
public class Battery {
    public String getPower() {
        return "電気が流れます!";
    }
}

このBatteryクラスは「電気を流せる電池」です。

車(ToyCarクラス)に電池を入れる

次に、ToyCar(おもちゃの車)にBatteryが必要なことを教えてあげます。

Java
import org.springframework.beans.factory.annotation.Autowired;

public class ToyCar {

    @Autowired  // Springがここに自動で電池を入れてくれる
    private Battery battery;

    public void start() {
        System.out.println(battery.getPower() + " 車が動きます!");
    }
}

ここでは、Springが自動でBatteryを用意して、ToyCarに入れてくれます。

車を動かす

Springが動いていると、ToyCarは自分でBatteryを探さなくても、誰かが電池を入れてくれた状態で「動く」ことができます。

コンストラクタへの依存性注入

今まででDIと@Autowiredの意味がつかめてきたでしょうか?

さっきの例で、ToyCarクラスに電池を渡す方法は「@Autowired」を使ってフィールドに直接入れるやり方でした。でも、もっと良い方法があります。それが、「コンストラクタを使って電池を入れる方法(コンストラクタへの依存性注入)」です。

コンストラクタって何?

コンストラクタというのは、新しいおもちゃ(クラス)が作られるときに最初に呼び出される「組み立てメソッド」のようなものです。このコンストラクタに電池を入れる(依存性を注入する)ことで、「電池が入っていないとおもちゃを作れないよ!」とルールを作ることができます。

例:コンストラクタを使って電池を入れる方法

  • 電池クラスはそのままです
Java
public class Battery {
    public String getPower() {
        return "電気が流れます!";
    }
}
  • ToyCarクラスで、コンストラクタを使って電池を受け取るようにします:
Java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class ToyCar {

    private final Battery battery;

    @Autowired  // Springがこのコンストラクタを使って電池を入れてくれる
    public ToyCar(Battery battery) {
        this.battery = battery;
    }

    public void start() {
        System.out.println(battery.getPower() + " 車が動きます!");
    }
}

どうしてコンストラクタで電池を渡すのが良いのか?

  1. 作るときに必要なものが分かる
    • コンストラクタで電池を渡すと、「このおもちゃは電池がないと動かない」とはっきり分かります。これにより、絶対に電池がないままおもちゃが作られることがなくなります。
  2. 後から変えられない
    • コンストラクタを使うと、電池が一度だけ入れられるため、あとから間違って別の電池が入れ替えられないようにできます。おもちゃが一度組み立てられたら、変えられない部品がある方が安全です。
  3. テストしやすい
    • テストのとき、違う種類の電池(たとえば、テスト用の特別な電池)をコンストラクタを通して簡単に入れられます。これはおもちゃの動作確認をする際に便利です。
  4. 必要なものが一目で分かる
    • コンストラクタの中身を見ると、このおもちゃには何が必要かがすぐに分かります。これで、他の人も見ただけで「このおもちゃは電池が必要なんだ!」と分かりやすくなります。

まとめ

私自身も概念の理解に苦しんだため、記事に残しました。
まとめると下記となります。

  • DIは、「このおもちゃには電池が必要」というように、必要なものを外から入れることです。
  • @Autowiredを使うと、Springが自動で「必要なもの」を入れてくれます。
  • 便利な理由は、どこに何が必要かがハッキリするので、分かりやすく、修理(変更)もしやすくなることです。
  • コンストラクタを使って依存性(電池)を注入する理由は、おもちゃを確実に組み立てられるようにするルールを決めるイメージです。このルールのおかげで、安全で、壊れにくく、後で直すのも簡単になります

この記事が少しでもお役に立てたら幸いです。

コメント

タイトルとURLをコピーしました