はじめに
Spring を触っていると必ず出てくる言葉、DI(依存性注入)。
「なんとなく聞いたことはあるけど、説明しようとするとむずかしい…」
そんな方も多いと思います。
この記事では、DI を やさしく・実務で役立つ形 で整理します。
まずはコードを見て、そこから少しずつ理解していきましょう。
まずはコードを確認
@Service
public class GreetingService {
public String greet() {
return "Hello!";
}
}
@RestController
public class HelloController {
private final GreetingService greetingService;
// ここが「依存性注入」
public HelloController(GreetingService greetingService) {
this.greetingService = greetingService;
}
@GetMapping("/hello")
public String hello() {
return greetingService.greet();
}
}
このコードでは、HelloController が GreetingService を使っています。
でも、自分で new GreetingService() はしていません。
ここが DI のポイントです。
コードのしくみを解説
DI(依存性注入)とは
「必要なもの(依存するオブジェクト)を、自分で作らずに外から渡してもらう仕組み」 のこと。
Spring が裏側で
オブジェクトを作って
必要な場所にそっと渡してくれる
そんな“お世話焼き”のような動きをしてくれます。
なんでそんなことをするの?
理由はシンプルで、
- テストしやすい
- 変更に強い
- コードがスッキリする
というメリットがあるからです。
例のコードで起きていること
- @Service をつけたクラス → Spring がインスタンスを作る
- HelloController のコンストラクタ → Spring が GreetingService を渡してくれる
- 開発者は「使うだけ」で OK
つまり、“作るのは Spring、使うのはあなた” という分担になっています。
あわせて知っておきたいポイント
DI の方法はいくつかある
- コンストラクタ注入(おすすめ)
- フィールド注入
- セッター注入
Spring では コンストラクタ注入が基本。
理由は「テストしやすい」「不変性が保てる」など、実務的なメリットが多いからです。
@Autowired は必須じゃない
コンストラクタが 1 つだけなら、@Autowired を書かなくても Spring が自動で注入してくれます。
Bean と DI はセットで理解するとスムーズ
DI は「Bean をどう渡すか」の話。
Bean の仕組みを軽く知っておくと理解が深まります。
使うときに気をつけたいこと
- 循環参照に注意
A が B を必要として、B が A を必要とする…
こうなると Spring が「どっちを先に作ればいいの?」となってしまいます。
- new で作らない
DI を使うなら、new で自分でインスタンスを作るのは NG。
Spring の管理外になり、注入されなくなります。
- Bean が見つからないエラー
No qualifying bean of type…
これは DI あるある。アノテーションの付け忘れ、パッケージスキャンの範囲外などが原因です。
まとめ
DI はむずかしく聞こえますが、
「必要なものを Spring がそっと渡してくれる仕組み」
と考えると、ふわっと理解できます。
実務でも DI は毎日のように使うので、
「なんとなくわかったかも」くらいでも十分スタートラインに立てます。

Spring の概念は最初とっつきにくいですが、
コードを触りながら少しずつ理解すると、急に視界がひらける瞬間があります。
あなたの開発が、今日よりちょっとだけ楽になりますように。

DI って、Spring さんが“はいどうぞ〜”って渡してくれる感じなんだね。やさしい世界……

コメント