はじめに
JavaでSpringを利用する際に理解しておかなければならない概念にDI(依存性注入)があります。
今回はDIについて学び、より優れたアーキテクチャーを作れるようになりましょう。
DI(依存性注入)とは?
DI(Dependency Injection / 依存性注入)というのは、「必要なものを外から渡す」という考え方です。たとえば、おもちゃの車を考えてみましょう。そのおもちゃは、電池がないと動きません。でも、おもちゃ自身が電池を探してきて入れることはできませんよね?なので、電池は外から誰かが入れてあげる必要があります。
プログラムでも同じように、クラス(プログラムの部品)が動くために、他の部品が必要なことがあります。このとき、必要な部品を外から渡すことを「依存性注入(DI)」と言います。
SpringでのDI
Spring(スプリング)はプログラムを組むときに便利なお手伝いツールです。このSpringは、「このクラスにはこれが必要」という情報を元に、必要な部品(オブジェクト)を外から自動で入れてくれます。
@Autowiredとは?
@Autowired
は、「この部分に必要なものをSpringに自動で入れてね!」とお願いするマークです。
アノテーションと言います。
どうしてDIが便利なの?
おもちゃの車が「電池が必要」と教えてあげると、家族みんながどこに電池を入れれば動くのか分かりやすくなりますよね。プログラムも同じで、DIを使うとクラス同士のつながりがハッキリします。だから、部品の変更や修理がしやすく、後でプログラムを見た人にも分かりやすくなります。
例を見てみよう
電池を必要とするおもちゃの車(クラス)を作る
車が電池を必要とすることを、@Autowired
を使ってSpringに教えます。
public class Battery {
public String getPower() {
return "電気が流れます!";
}
}
このBattery
クラスは「電気を流せる電池」です。
車(ToyCarクラス)に電池を入れる
次に、ToyCar
(おもちゃの車)にBattery
が必要なことを教えてあげます。
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」を使ってフィールドに直接入れるやり方でした。でも、もっと良い方法があります。それが、「コンストラクタを使って電池を入れる方法(コンストラクタへの依存性注入)」です。
コンストラクタって何?
コンストラクタというのは、新しいおもちゃ(クラス)が作られるときに最初に呼び出される「組み立てメソッド」のようなものです。このコンストラクタに電池を入れる(依存性を注入する)ことで、「電池が入っていないとおもちゃを作れないよ!」とルールを作ることができます。
例:コンストラクタを使って電池を入れる方法
- 電池クラスはそのままです
public class Battery {
public String getPower() {
return "電気が流れます!";
}
}
ToyCar
クラスで、コンストラクタを使って電池を受け取るようにします:
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() + " 車が動きます!");
}
}
どうしてコンストラクタで電池を渡すのが良いのか?
- 作るときに必要なものが分かる
- コンストラクタで電池を渡すと、「このおもちゃは電池がないと動かない」とはっきり分かります。これにより、絶対に電池がないままおもちゃが作られることがなくなります。
- 後から変えられない
- コンストラクタを使うと、電池が一度だけ入れられるため、あとから間違って別の電池が入れ替えられないようにできます。おもちゃが一度組み立てられたら、変えられない部品がある方が安全です。
- テストしやすい
- テストのとき、違う種類の電池(たとえば、テスト用の特別な電池)をコンストラクタを通して簡単に入れられます。これはおもちゃの動作確認をする際に便利です。
- 必要なものが一目で分かる
- コンストラクタの中身を見ると、このおもちゃには何が必要かがすぐに分かります。これで、他の人も見ただけで「このおもちゃは電池が必要なんだ!」と分かりやすくなります。
まとめ
私自身も概念の理解に苦しんだため、記事に残しました。
まとめると下記となります。
- DIは、「このおもちゃには電池が必要」というように、必要なものを外から入れることです。
@Autowired
を使うと、Springが自動で「必要なもの」を入れてくれます。- 便利な理由は、どこに何が必要かがハッキリするので、分かりやすく、修理(変更)もしやすくなることです。
- コンストラクタを使って依存性(電池)を注入する理由は、おもちゃを確実に組み立てられるようにするルールを決めるイメージです。このルールのおかげで、安全で、壊れにくく、後で直すのも簡単になります
この記事が少しでもお役に立てたら幸いです。
コメント