← Spring コース
44. ApplicationContext と Bean 定義
のは で表されます。コンテナが生成して組み立て、管理するを 、何をどう作るかの情報を と呼びます。 は、設定の印・・の3つをまとめたものです。スキャンは、これを付けたクラスのを起点に、配下の 付きクラスを探します。
前の回の自作コンテナは、頼まれた型をその場でたどるだけでした。Spring のコンテナは、設定クラスやスキャンの結果を読んで、何を生成して組み立てるかを知ります。 4.1.1 に だけを入れ、自分のクラスを4つ置いたアプリで定義を数えると 148 で、自分のものは 4 でした。残りの 144 は書いていない定義で、書いていないのに動く部分の実体です。
つまずきやすいのは起点です。起点の兄弟にあたるパッケージに @Component 付きのクラスを置いても、エラーにはならず、単に Bean として存在しません。別の Bean がそれを要求した時点で起動に失敗します。スキャンするパッケージは指定で足せるので、既定の起点がのパッケージ以下だ、という話です。なお 148 はこの最小構成での定義の数で、依存を足せば変わり、生成済みのインスタンスの数でもありません。
点線の付いた語はタップすると説明が出ます。用語集を開く →
@SpringBootApplication を付けたクラスl11.count.CountApp
このパッケージが起点3つをまとめて有効にする
コンポーネントスキャン起点の配下の @Component を探す
自動構成枠組みが用意した定義を登録する
設定クラスの印追加の Bean の登録などを書ける
登録される
自分のクラスの定義 4countApp・greetingService ほか
書いていない定義 144Spring Framework と Spring Boot が登録したもの
この定義をもとに生成・組み立て・管理する
ApplicationContext(コンテナ)Bean 定義 148
- ・148 と 144 は「Spring Boot 4.1.1 + spring-boot-starter-webmvc だけ + 自作4クラス」での値です。依存を1つ足せば変わります
- ・数えているのは定義の数で、生成済みのインスタンスの数ではありません。144 のうち、どれだけが自動構成から来たかの内訳は数えていません
- ・メインクラス自身も countApp という Bean になっていました(実測)
- ・自動構成が何をどう登録するかは、後のレッスンで扱います
サンプルコード(フレームワーク環境が必要なため表示のみ)
// l11/count/CountApp.java — コンテナに「定義はいくつあるか」を尋ねる
package l11.count;
import java.util.Arrays;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
@SpringBootApplication // このクラスのパッケージ(l11.count)がスキャンの起点になる
public class CountApp {
public static void main(String[] args) {
// run が返すのがコンテナ(ApplicationContext)
ConfigurableApplicationContext ctx = SpringApplication.run(CountApp.class, args);
System.out.println("context class = " + ctx.getClass().getName());
System.out.println("beanDefinitionCount = " + ctx.getBeanDefinitionCount());
String[] names = ctx.getBeanDefinitionNames();
long mine = Arrays.stream(names)
.filter(n -> ctx.getType(n) != null && ctx.getType(n).getName().startsWith("l11."))
.peek(n -> System.out.println(" mine: " + n + " -> " + ctx.getType(n).getName()))
.count();
System.out.println("my beans = " + mine);
// (先頭5つの定義名を出力する1行を省略)
ctx.close();
}
}
@Component class GreetingService {}
@Component("renamed") class URLParser {}
@Component class HTMLRenderer {}
// Spring Boot 4.1.1 / spring-boot-starter-webmvc だけ / JDK 25 での出力
// (ログ行とバナー、省略した1行ぶんの出力を除く。2回起動して2回とも同じ数)
//
// context class = org.springframework.boot.web.server.servlet.context.AnnotationConfigServletWebServerApplicationContext
// beanDefinitionCount = 148
// mine: countApp -> l11.count.CountApp
// mine: greetingService -> l11.count.GreetingService
// mine: HTMLRenderer -> l11.count.HTMLRenderer
// mine: renamed -> l11.count.URLParser
// my beans = 4
図やコードに出てくる用語(タップで説明)
サンプルコードで身につける(5本) →
学んだ概念を、素朴な例から実務寄りの例まで5つの具体例で確認します。
公式ドキュメントで詳しく ↗