お問い合わせ

【改訂版】第3章 DIの注入方法編|誰もが一度はつまずくSpring Bootを解説

このシリーズでは、Spring Bootで誰もが一度はつまずきやすいポイントを、Javaの経験が浅い方でも無理なく理解できるように、できるだけ難しい言葉を使わずに解説していきます。

今回は第3章「DIの注入方法編」です。前章では、DIがどのような仕組みで動くのかをイメージで理解しました。今回は、実際のコードではどのように注入するのか、その書き方を見ていきます。

DIの注入方法とは?

DIには、複数の注入方法があります。

今回は、その中でも代表的な3つの注入方法を取り上げて、それぞれの書き方と違いを順番に解説していきます。

代表的な3つの注入方法

代表的な注入方法は、次の3つです。

  1. フィールドインジェクション:フィールドに注入する
  2. セッターインジェクション:セッターメソッドに注入する
  3. コンストラクタインジェクション:コンストラクタに注入する

名前は少し難しそうですが、まず注目したい違いは「どこに注入するか」です。つまり、3つの違いは注入する場所にあります。

それでは、それぞれの書き方と特徴を、ひとつずつ順番に見ていきましょう。

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

1つ目は、フィールドインジェクションです。これは、前の章で使った方法です。

@RestController
public class MainController {

  @Autowired
  private MainService mainService;

}

フィールドに @Autowired を付けることで、Springが必要なインスタンスを、そのフィールドへ直接注入します。

記述量が少なく、見た目がシンプルなのが特徴です。

セッターインジェクション

2つ目は、セッターインジェクションです。

private MainService mainService;

@Autowired
public void setMainService(MainService mainService) {
  this.mainService = mainService;
}

セッターメソッドに @Autowired を付けることで、Springがそのメソッドを通して注入します。

セッターインジェクションでは、インスタンスの生成後にも設定や変更ができます。そのため、そのクラスを動かすうえで、必ずしも必要ではないクラスを注入する場合に向いています。このような依存関係を、「任意の依存関係」と呼びます。

コンストラクタインジェクション

3つ目は、コンストラクタインジェクションです。

private final MainService mainService;

@Autowired
public MainController(MainService mainService) {
  this.mainService = mainService;
}

コンストラクタの引数として必要なインスタンスを受け取り、インスタンスが生成されるタイミングで注入されます。

大きな特徴は、フィールドに final を付けられることです。final を付けると、注入されたインスタンスを後から別のインスタンスに差し替えられなくなります。そのため、意図しない書き換えを防ぎ、より安全なコードにできます。

@Autowired を省略できるケース

コンストラクタインジェクションについて、もう1つ覚えておきたいポイントがあります。

クラスにコンストラクタが1つだけの場合、@Autowired は省略できます。

private final MainService mainService;

public MainController(MainService mainService) {
  this.mainService = mainService;
}

先ほどのコードから @Autowired を外しても、Springはそのコンストラクタを使って自動で注入してくれます。

実務では @Autowired を省略して書くことが多いため、この形にも慣れておきましょう。

3つの注入方法を比較

ここまでに紹介した3つの注入方法を、表で整理してみましょう。

注入方法注入する場所主な特徴
フィールドインジェクションフィールド記述量が少ない
セッターインジェクションセッターメソッド後から設定・変更できる
コンストラクタインジェクションコンストラクタ必須の依存関係を明確にできる

推奨される注入方法

では、3つのうち、どれを使えばよいのでしょうか。

結論から言うと、基本はコンストラクタインジェクションです。理由は3つあります。

  1. コンストラクタを見れば、必要なクラスがひと目で分かる
  2. インスタンスの生成時に、必須の依存関係を確実に受け取れる
  3. フィールドを final で固定し、意図しない書き換えを防げる

この3つの理由から、基本はコンストラクタインジェクションを使うと覚えておきましょう。

まとめ

「DIの注入方法編」の内容をまとめます。ポイントは2つです。

  1. DIでの代表的な注入方法は、フィールド・セッター・コンストラクタの3つ
  2. 必須の依存関係には、コンストラクタインジェクションを使うのが基本

この2つを押さえておけば大丈夫です。

次の章では、注入の対象となるBeanが、Springにどのように登録されるのかを解説します。