Dev Study
← 解説「Spring・Spring Framework・Spring Boot・Bean・DI コンテナ」に戻る

サンプルコードで身につける: Spring・Spring Framework・Spring Boot・Bean・DI コンテナ

解説で学んだ概念を、5つの具体例で確認します。素朴な例から実務寄りの例へと進みます。

1用語早見表: Spring の用語

このレッスンの用語を1つずつ並べた表です。本文で扱ったのは ・・・・で、残りは後のレッスンで扱います。「近いもの」はたとえで、当たらない点は5本目にまとめました。

用語早見表(Spring・Bean・DI コンテナ ほか)表
用語 | 一言で
手元では: 何として見えるか
近いもの: NestJS で近いもの
 
Spring | 単独で言うときは、Spring Framework を土台にした
プロジェクト群の総称であることが多い
近いもの: 無い
 
Spring Framework | 土台。DI コンテナと、Web・データアクセス
などの機能群
手元では: spring-context-7.0.9.jar などの JAR
近いもの: NestJS(役割だけ)
 
Spring Boot | その上で、単独で起動できるアプリを
少ない設定で作れるようにするもの
手元では: spring-boot-starter-... という依存
近いもの: 独立したものは無い
 
Bean | Spring のコンテナが作り、組み立て、管理するオブジェクト
手元では: @Component などを付けたクラスのインスタンス
近いもの: プロバイダのインスタンス
 
DI コンテナ / IoC コンテナ | Bean を作り、必要な相手を渡す役
手元では: ApplicationContext
近いもの: NestJS の DI コンテナ
 
ApplicationContext | Spring のコンテナを表すインターフェース
手元では: SpringApplication.run の戻り値
近いもの: 対応を確かめていない
 
依存性の注入(DI) | 必要な相手を自分で作らず、
コンストラクタの引数などで受け取ること
手元では: コンストラクタの引数
近いもの: NestJS のコンストラクタでの注入
 
アノテーション | クラスやメソッドに付ける印。それ自体は何もしない
手元では: @Component、@GetMapping
近いもの: デコレータ(見た目が同じだけで別物)
 
コンポーネントスキャン | クラスパスを走査して、印の付いた
クラスを Bean として登録すること
手元では: 起動クラスのパッケージ以下が既定の対象
近いもの: 無い(NestJS はモジュールに自分で並べる)
 
自動構成 | クラスパスにある JAR を見て、Spring Boot が
Bean の設定を自動で足すこと
手元では: 自分では書いていない Bean
近いもの: 対応を確かめていない
 
スターター | ある用途に必要な依存をひとまとめにした依存の記述
手元では: spring-boot-starter-webmvc
近いもの: @nestjs/... のパッケージ群(用途ごと、という点だけ)
 
AOP | メソッド呼び出しの前後に処理を挟む仕組み
Aspect-oriented Programming の略
近いもの: 対応を確かめていない
 
プロキシ | AOP のために、本物の代わりに渡される代理のオブジェクト
手元では: クラス名に $$SpringCGLIB$$ が入った Bean
近いもの: 対応を確かめていない
 
Spring MVC | Servlet の API の上に作られた Web フレームワーク
Spring Framework の一部
手元では: @RestController、@GetMapping
近いもの: NestJS のコントローラの層

2最小のアプリの中で、用語が指すものを探す

の雛形のと、足したコントローラ1つです。自分で new を書いていないのに HelloController が動くのは、がこのを見つけて Bean として作るからです。コメントは説明のために足したもので、元のファイルにはありません。

// DemoApplication.java — start.spring.io の雛形のまま(コメントは追記)
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// アノテーション。Bean の定義を書けるクラスの印・自動構成・コンポーネントスキャンの
// 3つを1つにまとめたもの
@SpringBootApplication
public class DemoApplication {

	public static void main(String[] args) {
		// Spring Boot の入口。この中で DI コンテナ(ApplicationContext)が作られ、
		// Bean が生成される。戻り値がそのコンテナ
		SpringApplication.run(DemoApplication.class, args);
	}

}

// HelloController.java — 自分で足したクラス(コメントは追記)
// package と import の行は省略

// Spring MVC のアノテーション。このクラスはコンポーネントスキャンで
// 見つかり、Bean になる。new はどこにも書いていない
@RestController
public class HelloController {

	// GET /hello に来た要求を、このメソッドに対応づける
	@GetMapping("/hello")
	public String hello() {
		return "Hello from Spring Boot";
	}

}

// 起動ログから(Spring Boot 4.1.1 / JDK 25。スターターが連れてきた Tomcat が動く)
//   Tomcat started on port 8080 (http) with context path '/'

3コンテナの中の Bean を数える

自分のクラスを4つ置いた最小の Web アプリで、コンテナが持つ を数えた出力です。1行目が の実際のクラス、強調した行が定義の総数で、自分のものは4つでした。残りは自分では書いていない定義です。Spring Boot 4.1.1 に webmvc のだけを入れた場合の値で、依存を足せば変わります。

コンテナに Bean の定義の数を尋ねた出力(Spring Boot 4.1.1 / 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

4JavaBeans と Spring の Bean は別物

の java.beans に、2つのクラスの「 としてのプロパティ」を尋ねるコードです。getName / setName の形を持つ Customer には2つ見つかり、で受け取るだけの OrderService には1つも見つかりません。 の Bean になれるかどうかはこの決まりと関係がなく、OrderService の形で構いません。

Java

5たとえが当たらない点: NestJS との違い

Spring Framework を NestJS、Bean をプロバイダのに置き換えると読みやすくなりますが、どれもたとえです。特に、アノテーションとデコレータは見た目が同じだけで別物です。最後に、名前が似ている3つの Bean も並べました。

Spring の用語と NestJS の用語: 当たる点と当たらない点表
Spring Framework(と Spring MVC)と NestJS
当たる点 : DI コンテナと、コントローラなどの部品の決まった形を
与える。HTTP は下の層に任せる
当たらない点: Java では型が実行時に残るので、注入する相手の
決め方が違う。モジュールの providers / exports に
当たる、見える範囲を区切る仕組みが無い
 
Spring Boot
当たるもの : NestJS には独立しては無い
NestJS は最初からサーバを内蔵し main.ts から起動する。
Spring ではそれが後から Spring Boot として足された
 
Bean とプロバイダのインスタンス
当たる点 : コンテナが作って注入するオブジェクト
当たらない点: NestJS のコントローラはプロバイダと別枠
(controllers に並べる)。Spring ではコントローラも Bean
 
アノテーションとデコレータ
当たる点 : @ で始まる見た目
当たらない点: デコレータは実行時に呼ばれる関数。
アノテーションは読まれるまで何もしない印(データ)
 
スターターと @nestjs/... のパッケージ群
当たる点 : 用途ごとの依存のまとまり
当たらない点: スターター自体はほぼ中身の無い JAR で、
依存を連れてくるだけ
 
Spring の Bean と JavaBeans と EJB
3つとも別物 : Bean は「コンテナが管理しているオブジェクト」
JavaBeans は「getter / setter などの名前の決まりに
従ったクラス」
EJB(Enterprise JavaBeans)はサーバ側の部品の仕様

図やコードに出てくる用語(タップで説明)