[Java] DIの「中身」はどこまで知るべき? 脱・初心者のための学習ライン

こんにちは。ゆうせいです。

「AOPの仕組みは知っておくべき」という話をしたので、「じゃあDIも全部知らなきゃいけないの?」と不安になってしまいますよね。

結論から言います。

DIに関しては、「裏側の難しいプログラム」は知らなくていいですが、「どういうルールで動いているか」は絶対に知る必要があります。

これだけだと少し分かりにくいので、「知らなくていいこと」と「知っておくべきこと」を明確に分けて解説しますね。


1. 知らなくていいこと(車のエンジンの話)

まず、安心してください。以下の深い仕組みについては、今の段階では知らなくて大丈夫です。

  • リフレクション(Reflection)Springが裏側で使っている、クラスを勝手に解析したり書き換えたりするJavaの高度な技術です。
  • Bean定義の読み込み順序Springが起動するときに、どの設定ファイルをどの順番で読んでいるか、といった細かい内部挙動です。

これらは、車で例えるなら「エンジンの燃焼システム」や「ガソリンが爆発する化学反応」のようなものです。

エンジニアが車を作りたいなら知る必要がありますが、車を運転する(アプリを作る)だけなら、そこまで知らなくても目的地には着けます。

2. 知っておくべきこと(交通ルールの話)

一方で、仕組みを知らないと大事故につながるポイントが一つだけあります。

これは車で言う「右側通行か左側通行か」くらい重要なルールです。

それは、「Springが作る部品(Bean)は、世界に一つしかない」 ということです。

専門用語で 「シングルトン(Singleton)」 と言います。

シングルトンの恐怖

どういうことか、例を見てみましょう。

あなたは「ユーザーがお金を預ける銀行クラス」を作ったとします。

Java

@Service
public class BankService {
    // 預金額を記録する変数
    private int balance = 0;

    public void deposit(int money) {
        this.balance = this.balance + money;
    }

    public int getBalance() {
        return this.balance;
    }
}

このクラスをSpringのDIで使うと、どうなるでしょうか?

Springの倉庫(IoCコンテナ)は、この BankService のインスタンス(実体)を 1つだけ 作ります。

そして、Aさんがアクセスしても、Bさんがアクセスしても、全員に「同じ1つのインスタンス」を使い回して渡します。

その結果、こんな事故が起きます。

  1. Aさんが1000円預ける。(balance は 1000 になる)
  2. Bさんがログインして残高を見る。
  3. なぜかBさんの残高が1000円になっている!
  4. Bさんがびっくりして1000円引き出す。(balance は 0 になる)
  5. Aさんが残高を見ると、お金が消えている!

これは、DIされた部品が「みんなで共有されている」という仕組みを知らないために起こる、もっとも恐ろしいバグです。

学ぶべき教訓

DIの仕組みとして、これだけは覚えておいてください。

  • DIされるクラス(@Serviceや@Controller)には、変化するデータ(フィールド変数)を持たせてはいけない。
  • データはメソッドの引数で渡して、その場だけで使う。

「DIはインスタンスを使い回している」という仕組みを知っているだけで、この事故は防げます。

3. もう一つの壁「循環参照」

もう一つ、仕組みとして知っておくべきなのが 「循環参照(じゅんかんさんしょう)」 です。

  • クラスAは、クラスBを注入してほしい。
  • クラスBは、クラスAを注入してほしい。

この二つを定義すると、Springの管理人は困ってしまいます。

「Aを作るにはBが必要だけど、Bを作るにはAが必要で、Aを作るにはBが必要で……」と無限ループに陥り、アプリが起動しなくなります(エラーが出ます)。

これも「DIは最初に部品を組み立てて注入する」という仕組みをイメージできていれば、「ああ、お互いに欲しがってるから作れないんだな」とすぐに原因が分かります。

まとめ

DIの仕組みについては、以下のようなスタンスで学習を進めてください。

  • どうやって注入しているか(技術)今は知らなくてOK。「Springがよしなにやってくれている」と思っていてください。
  • 注入された部品はどう扱われるか(ルール)これは必須です。特に「部品は1つだけで、みんなで使い回す(シングルトン)」という点は、今日必ず覚えて帰ってください。

今後の学習の指針

これでSpring Frameworkの「DI」と「AOP」という2大要素の概念は掴めたはずです!

もし学習環境があれば、先ほどの「銀行クラス」の失敗例を実際に作ってみてください。

ブラウザを2つ立ち上げて(例えばChromeとEdge)、片方で数字を増やすと、もう片方でも勝手に増えている現象を確認できるはずです。

「うわ、本当に共有されてる!」と実感できれば、もうシングルトンの落とし穴に落ちることはありません。

さあ、怖がることはありません。仕組みという地図を持って、Springの世界をどんどん探検していきましょう!

それでは、また次の記事でお会いしましょう。

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。