本文へスキップ
BecomeCoder

Spring / Spring Bootコース · 第2章 Bean と DIコンテナ ― Springに管理してもらう部品たち · レッスン6

ApplicationContext ― 起動からBean取得までの流れ

ローカル実施

導入

@Component@Bean でBeanの「作り方」を教えることは分かりました。では実際にSpringが起動するとき、これらの情報を使って何が起きているのかを俯瞰してみましょう。

説明

DIコンテナの実体は ApplicationContext というオブジェクトです。Springアプリが起動すると、ApplicationContextが次の手順でBeanを組み立てます。

sequenceDiagram
    participant Main as main()
    participant Ctx as ApplicationContext
    Main->>Ctx: 起動する
    Ctx->>Ctx: コンポーネントスキャン(@Component等を収集)
    Ctx->>Ctx: @Configuration の @Bean 定義も収集
    Ctx->>Ctx: 各Beanが必要とする依存関係を解決する
    Ctx->>Ctx: 依存の順にインスタンス化し、コンストラクタへ注入する
    Ctx-->>Main: 全Beanの組み立てが完了(起動完了)

ここで重要なのは、開発者は「何が必要か」を宣言するだけで、「誰が」「どの順番で」インスタンスを作るかはApplicationContextが解決してくれる、という点です。

ApplicationContext context = SpringApplication.run(MyApp.class, args);

// Beanを直接取り出すこともできる(通常はDIで受け取るので、あまり書かない)
OrderService service = context.getBean(OrderService.class);

普段のアプリ開発では context.getBean(...) を直接呼ぶことはほとんどありません。コンストラクタインジェクションで「必要な依存を宣言する」だけで、裏側のApplicationContextがすべて配線してくれるからです。この「裏側で自動的に組み立てられている」という感覚を持てると、Springのコードが急に読みやすくなります。

やってみよう

OrderServiceNotifier を必要とし、Notifier の実装 MailNotifier がさらに何か(例えば MailClient)を必要とする、という3段の依存関係を想像してみましょう。ApplicationContextはこの3つをどの順番で組み立てる必要があるか、図に書き出してみてください。