- Spring
Spring Boot 4移行の手順|3から4の変更点一覧とチェックリスト
Spring Boot 4への移行とは、3.5系の最新版で非推奨の警告をなくしたうえで、スターターの細分化・Jackson 3・テスト用アノテーションの変更に順番に対応していく作業です。 一度に全部を直すのではなく、公式が用意している「classic スターター」を足場にして、ビルドが通る状態を保ったまま段階的に進められます。
この記事では、公式の Spring Boot 4.0 Migration Guide の章立てに沿って変更点を一覧にし、それぞれが「コンパイルで分かる/テストで分かる/黙って挙動が変わる」のどれに当たるかを列で示します。旧名と新名の対応表、世代別のサポート期限、3 系の書き方を探すスクリプト(出力つき)、そのまま貼れるチェックリストもまとめました。
確認環境:Spring Boot 4.1.1/3.5.16 の公式リファレンスと Migration Guide・4.1 Release Notes で確認(確認日 2026年10月7日)。検出スクリプトは Ubuntu 24.04・Python 3.11.15 で実行しています。
Spring Boot 4移行の早見表
| 順 | やること | 完了の目安 |
|---|---|---|
| 1 | 3.5系の最新版(3.5.16)へ上げる | ビルドとテストが通る |
| 2 | 非推奨の警告を解消する | コンパイル時の非推奨警告が 0 件 |
| 3 | classic スターターで 4.1.1 に上げる | コンパイルが通る |
| 4 | スターターを技術ごとに置き換える | classic を外しても起動する |
| 5 | Jackson 3 に合わせる | JSON の入出力テストが通る |
| 6 | テストのアノテーションを直す | 全テストが通る |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Spring Boot 4移行の手順|3から4の変更点一覧とチェックリスト」
いつまでに上げるかをサポート期限から決める
3.5系の無償(OSS)サポートは 2026年6月30日に終了しており、4.0系も 2026年12月31日までです。 これから移行するなら、行き先は 4.1系(OSS サポート 2027年7月31日まで)にするのが素直です。下の表は api.spring.io の世代一覧から、3.4 以降を抜き出したものです(確認日 2026年10月7日)。
| 世代 | 初回リリース | OSS 終了 | 商用終了 |
|---|---|---|---|
| 3.4.x | 2024-11-30 | 2025-12-31 | 2026-12-31 |
| 3.5.x | 2025-05-31 | 2026-06-30 | 2032-06-30 |
| 4.0.x | 2025-11-30 | 2026-12-31 | 2027-12-31 |
| 4.1.x | 2026-06-30 | 2027-07-31 | 2028-07-31 |
| 4.2.x | 2026-11-30 | 2027-12-31 | 2028-12-31 |
公式のサポート方針では、メジャー版はリリースから少なくとも3年、マイナー版は少なくとも12か月サポートされ、新しいメジャー・マイナーはおよそ半年ごと(5月と11月)に出ます。この周期を前提に、次のように決めると迷いません。
| 今の状態 | 進め方の目安 |
|---|---|
| 3.4 以前を使っている | まず 3.5.16 へ。ここまでは 3 系の中の更新 |
| 3.5 を OSS 版で使っている | OSS の修正提供は終了済み。4.1 への移行を計画に入れる |
| 3.5 を商用サポートで使っている | 2032-06-30 まで期間がある。移行は機能追加の区切りに合わせられる |
| 4.0 を使っている | 2026-12-31 までに 4.1 へ。変更点は少ない(後述) |
| これから 4 系に上げる | 4.1.1 を行き先にする。4.2 は 2026-11-30 の予定 |
3から4の変更点一覧(公式移行ガイドの章立て順)
「気づく場面」の列は、コンパイル=ビルドの時点でエラーになる、テスト=テストや起動で失敗として現れる、黙って=エラーにならずに動きだけが変わる、の3つで示します。「黙って」の行は、確認用のテストを先に書いてから上げると安心です。
要件
| 項目 | 4.0 の基準 | 気づく場面 |
|---|---|---|
| Java | 17 以上 | コンパイル |
| Kotlin | 2.2 以上 | コンパイル |
| GraalVM native-image | 25 以上 | コンパイル |
| Jakarta EE | 11 が基準 | コンパイル |
| Servlet | 6.1 が基準 | テスト |
| Spring Framework | 7.x | コンパイル |
4.1 では jOOQ の対応版が 3.20 になり、jOOQ を使う場合は Java 21 以上が必要です。
削除された機能
| 機能 | 4.0 での扱い | 気づく場面 |
|---|---|---|
| Undertow | Servlet 6.1 に対応しないためスターターごと削除 | コンパイル |
| Pulsar Reactive | 自動構成を削除 | コンパイル |
| 起動スクリプト埋め込みの実行可能 JAR | 削除。java - などで起動する |
テスト |
| Spring Session Hazelcast | Boot からの直接サポートを削除 | コンパイル |
| Spring Session MongoDB | Boot からの直接サポートを削除 | コンパイル |
| Spock 連携 | Groovy 5 に対応していないため削除 | コンパイル |
| CLASSIC ローダー | loader の設定ごと削除 |
コンパイル |
モジュールとスターター
4.0 では自動構成が技術ごとの小さなモジュールに分かれました。命名は、モジュールが spring-boot-<技術>、スターターが spring-boot-starter-<技術>、テスト用が spring-boot-starter-<技術>-test です。
| 項目 | 3.x | 4.x | 気づく場面 |
|---|---|---|---|
| Flyway | flyway- だけで動く |
spring- が必要 |
黙って |
| Liquibase | liquibase- だけで動く |
spring- が必要 |
黙って |
| Web MVC | spring- |
spring-(旧名は非推奨で残る) |
コンパイル(警告) |
| AOP | spring- |
spring- |
コンパイル |
| テスト用スターター | spring- 1つ |
技術ごとの - スターターを追加 |
コンパイル |
Flyway と Liquibase を「黙って」としたのは、ライブラリ本体は残るのでコンパイルは通り、Boot 側の自動構成だけが外れるためです。起動時にテーブルができているかを確かめるテストがあると、ここで気づけます。
コア機能
| 項目 | 4.0 での変更 | 気づく場面 |
|---|---|---|
| null 注釈 | JSpecify の注釈を採用。org. からの移行を推奨 |
コンパイル |
| Logback の文字コード | ファイル出力の既定が UTF-8 | 黙って |
Bootstrap |
org. へ移動 |
コンパイル |
Environment |
org. へ移動(旧も非推奨で残る) |
コンパイル(警告) |
Property |
null のとき変換・判定を呼ばない。必要なら always( |
黙って |
| DevTools のライブリロード | 既定で無効。spring. で有効 |
黙って |
依存関係とビルドプラグイン
| 項目 | 4.0 での変更 | 気づく場面 |
|---|---|---|
| Maven の optional 依存 | 実行可能 JAR に含めない。必要なら <include |
テスト |
| Spring Retry | 依存管理から外れた。使い続けるなら版を明示 | コンパイル |
| Spring Authorization Server | Spring Security 7.0 に統合。spring- で版を指定 |
コンパイル |
| CycloneDX Gradle プラグイン | 3.0.0 以上 | コンパイル |
| Hibernate | hibernate- は hibernate- へ |
コンパイル |
Jackson 3
| 項目 | 3.x(Jackson 2) | 4.x(Jackson 3) | 気づく場面 |
|---|---|---|---|
| パッケージ | com. |
tools.(jackson- は元のまま) |
コンパイル |
| カスタマイザー | Jackson2 |
Json |
コンパイル |
| 部品の登録 | @Json/@Json |
@Jackson/@Jackson |
コンパイル |
| 読み書きの設定 | spring./write. |
spring./json. |
黙って |
| モジュール登録 | よく使われるものだけ自動 | クラスパス上のすべてを自動登録 | 黙って |
Actuator と Web
| 項目 | 4.0 での変更 | 気づく場面 |
|---|---|---|
| エンドポイント引数の null 注釈 | org. を使う |
テスト |
| liveness/readiness | 既定で有効。management. で無効 |
黙って |
| 静的リソース | Path に / が加わる |
黙って |
| Spring Session の設定 | spring. は spring. へ |
黙って |
Http |
非推奨。Client/Server へ |
コンパイル(警告) |
server. |
war 配備では効かない | 黙って |
| war 配備の Tomcat | spring- に変更 |
テスト |
データ
| 項目 | 4.0 での変更 | 気づく場面 |
|---|---|---|
| Elasticsearch | Rest5 に切り替え。Rest5 を使う |
コンパイル |
@Entity |
org. |
コンパイル |
| 例外変換の設定 | spring. |
黙って |
| MongoDB の接続設定 | spring. の多くが spring. へ |
黙って |
| MongoDB の UUID/BigDecimal | 既定値がなくなり明示が必要 | テスト |
メッセージングとバッチ
| 項目 | 4.0 での変更 | 気づく場面 |
|---|---|---|
| Kafka Streams | Stream を削除。Streams へ |
コンパイル |
| Kafka のリトライ | spring. は …backoff. へ |
黙って |
| AMQP のリトライ | Rabbit/Rabbit へ |
コンパイル |
| Spring Batch | spring- はメモリ上で動く。DB に保存するなら spring- |
黙って |
Spring Batch は影響が見えにくい変更です。スターター名をそのままにして上げると、ジョブのメタデータが既存のデータベースに保存されなくなります。履歴テーブルを参照している処理がある場合は、先に spring-boot-starter-batch-jdbc へ切り替えます。
テスト
| 項目 | 3.x | 4.x | 気づく場面 |
|---|---|---|---|
| モック | @Mock/@Spy |
@Mockito/@Mockito |
コンパイル |
@Mock/@Captor |
Mockito が処理 |
Mockito を付ける |
テスト |
| MockMvc | @Spring だけで使える |
@Auto を付ける |
テスト |
Test |
@Spring だけで使える |
@Auto と依存2つ |
コンパイル |
@Property |
…test. |
org. |
コンパイル |
旧名から新名への対応表
スターター
| 旧(3.x) | 新(4.x) |
|---|---|
spring- |
spring- |
spring- |
spring- |
spring- |
spring- |
spring- |
spring- |
spring- |
spring- |
spring- |
spring- |
flyway- のみ |
spring- |
liquibase- のみ |
spring- |
spring-(DB 保存) |
spring- |
spring-(war 配備) |
spring- |
spring- |
spring- または spring- |
よく使うスターターとテスト用スターター
| 技術 | 本体 | テスト用 |
|---|---|---|
| Web MVC | spring- |
spring- |
| WebFlux | spring- |
spring- |
| RestClient/RestTemplate | spring- |
spring- |
| WebClient | spring- |
spring- |
| Validation | spring- |
spring- |
| JDBC | spring- |
spring- |
| Spring Data JPA | spring- |
spring- |
| Spring Data Redis | spring- |
spring- |
| Flyway | spring- |
spring- |
| Liquibase | spring- |
spring- |
| キャッシュ | spring- |
spring- |
| Jackson | spring- |
spring- |
| Security | spring- |
spring- |
| Thymeleaf | spring- |
spring- |
| Kafka | spring- |
spring- |
| AMQP | spring- |
spring- |
| Actuator | spring- |
spring- |
このほかの技術も同じ規則で名前が付いています。全件は公式移行ガイドの Starters の表にあります。
クラスとアノテーション
| 旧(3.x) | 新(4.x) |
|---|---|
com. |
tools. |
Jackson2 |
org. |
Json |
Object |
Json |
Object |
@Json |
org. |
@Json |
@Jackson |
@Mock |
org. |
@Spy |
@Mockito |
org. |
org. |
@Auto(旧パッケージ) |
org. |
org. |
org. |
Rest(Elasticsearch) |
Rest5 |
Stream |
Streams |
Rabbit |
Rabbit/Rabbit |
設定プロパティ
| 旧(3.x) | 新(4.x) |
|---|---|
spring. |
spring. |
spring. |
spring. |
spring. |
spring. |
spring. |
spring. |
spring. |
spring. |
spring. など接続系 |
spring. など |
management. |
management. |
management. |
management. |
spring. |
spring. |
spring. |
spring. |
spring- |
spring- |
4.0から4.1で加わる変更
4.0 を経由せずに 4.1.1 へ上げる場合は、次の点も合わせて確認します(4.1 Release Notes より)。
| 項目 | 4.1 での変更 | 気づく場面 |
|---|---|---|
| 4.0 で非推奨だったもの | 削除 | コンパイル |
jarmode= |
削除。jarmode= を使う |
テスト |
Maven の - |
AOT 処理は省かれない。省くのは maven. |
黙って |
| Derby 連携 | 非推奨。H2 や HSQL を検討 | コンパイル(警告) |
JPA の bootstrap- |
Async の Bean が必要 |
テスト |
| jOOQ | 3.20(Java 21 以上) | コンパイル |
| DevTools の LiveReload | 非推奨 | コンパイル(警告) |
Dockerfile で -Djarmode=layertools を使っている場合は、4.1 に上げる前に -Djarmode=tools へ書き換えておきます。
手順1と2:3.5最新版に上げて非推奨をなくす
3 系で非推奨だったクラス・メソッド・プロパティは 4.0 で削除されています。 先に 3.5.16 へ上げて警告を消しておくと、4 に上げたときのエラーが「4 で変わったこと」だけになり、原因を切り分けやすくなります。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.16</version>
</parent>
非推奨の利用箇所は、コンパイラの -Xlint:deprecation で1件ずつ場所が出ます。付けない場合は「非推奨の API を使っています」という注記だけになります。Java 21 で、@Deprecated を付けたメソッドを呼ぶ2ファイルをコンパイルした出力です。
$ javac -cp out -d out Legacy.java
Note: Legacy.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
$ javac -Xlint:deprecation -cp out -d out Legacy.java
Legacy.java:3: warning: [deprecation] oldName() in OldApi has been deprecated
System.out.println(OldApi.oldName());
^
1 warning
Maven や Gradle でも、コンパイラの引数にこのオプションを渡せば同じ形式で一覧が出ます。@MockBean のように「3.4.0 で非推奨、4.0.0 で削除」と API ドキュメントに書かれているものは、この段階で置き換えられます。
設定プロパティの名前変更は、公式が用意している spring-boot-properties-migrator を一時的に入れると、起動時に診断して実行時だけ読み替えてくれます。移行が終わったら外すのが前提の部品です。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-properties-migrator</artifactId>
<scope>runtime</scope>
</dependency>
runtimeOnly("org.springframework.boot:spring-boot-properties-migrator")
手順3:classicスターターで4に上げる
classic スターターは、すべてのモジュールをまとめて入れることで 3 系に近い構成を再現する足場です。 まずこれでビルドを通し、そのあとで技術ごとのスターターに置き換えます。
直す前(3.5.16):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.16</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
直した後(4.1.1・classic で足場を作る):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>4.1.1</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-classic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test-classic</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
classic スターターは「すべてのモジュールを含むが、その先の推移的な依存は除く」構成です。公式も最終的には classic から離れることを勧めているので、次の手順まで進めて完了とします。
手順4:スターターを技術ごとに置き換える
使っている技術を1つずつ専用スターターに置き換え、最後に classic を外します。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-flyway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-flyway-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Gradle(Kotlin DSL)では次のようになります。
dependencies {
implementation("org.springframework.boot:spring-boot-starter-webmvc")
implementation("org.springframework.boot:spring-boot-starter-flyway")
testImplementation("org.springframework.boot:spring-boot-starter-webmvc-test")
testImplementation("org.springframework.boot:spring-boot-starter-flyway-test")
}
置き換えの順番は、起動時に結果が目で見えるもの(Web → DB マイグレーション → データアクセス)から進めると、足りないスターターにすぐ気づけます。
手順5:Jackson 3に合わせる
Jackson 3 ではグループ ID とパッケージが com.fasterxml.jackson から tools.jackson に変わります。例外は jackson-annotations で、com.fasterxml.jackson.annotation のまま使えます。 つまり @JsonProperty や @JsonInclude の import は直さずに済みます。
直す前(3.5):
package com.example.demo;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.stereotype.Component;
@Component
public class JsonCustomizer implements Jackson2ObjectMapperBuilderCustomizer {
@Override
public void customize(Jackson2ObjectMapperBuilder builder) {
// ここで builder を調整する
}
}
直した後(4.1):
package com.example.demo;
import com.fasterxml.jackson.annotation.JsonInclude; // annotation はそのまま
import tools.jackson.databind.json.JsonMapper;
import org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer;
import org.springframework.stereotype.Component;
@Component
public class JsonCustomizer implements JsonMapperBuilderCustomizer {
@Override
public void customize(JsonMapper.Builder jsonMapperBuilder) {
// ここで jsonMapperBuilder を調整する
}
}
設定ファイルは、JSON の読み書きの機能(JsonReadFeature/JsonWriteFeature)を切り替えるキーに json. が入ります。
# 直す前(3.5)
spring.jackson.read.<機能名>=true
spring.jackson.write.<機能名>=true
spring.jackson.parser.<機能名>=true
# 直した後(4.1)
spring.jackson.json.read.<機能名>=true
spring.jackson.json.write.<機能名>=true
spring.jackson.json.read.<機能名>=true
spring.jackson.serialization.*(例:spring.jackson.serialization.indent_output=true)や spring.jackson.deserialization.*、spring.jackson.mapper.*、spring.jackson.default-property-inclusion は 4.1.1 のリファレンスに載っている名前です。
Jackson 3 への対応に時間が必要な場合のために、公式は2つの橋渡しを用意しています。
| 方法 | 設定 | 位置づけ |
|---|---|---|
| 既定値を Jackson 2 に寄せる | spring. |
Jackson 3 を使いつつ挙動を近づける |
| Jackson 2 の自動構成を使う | spring- を追加(設定は spring.) |
非推奨の形で提供される一時的な手段 |
| モジュールの自動登録を止める | spring. |
4 で全モジュール登録になった点を戻す |
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-jackson2</artifactId>
</dependency>
自動構成の Mapper を差し替えたい場合は、ObjectMapper ではなく JsonMapper(XML なら XmlMapper)の Bean を定義します。
手順6:テストのアノテーションを直す
4.0 では @SpringBootTest だけでは MockMvc も TestRestTemplate も用意されません。使うものをアノテーションで明示します。
直す前(3.5):
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
class TaskControllerTest {
@Autowired
MockMvc mvc;
@MockBean
TaskService taskService;
@Test
void list() throws Exception {
mvc.perform(get("/tasks")).andExpect(status().isOk());
}
}
直した後(4.1):
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
class TaskControllerTest {
@Autowired
MockMvc mvc;
@MockitoBean
TaskService taskService;
@Test
void list() throws Exception {
mvc.perform(get("/tasks")).andExpect(status().isOk());
}
}
変わるのは import 2行とアノテーション1つです。テストの種類ごとの対応は次のとおりです。
| 使っているもの | 4 系で付けるもの | 必要な依存 |
|---|---|---|
Mock |
@Auto |
spring- |
Test |
@Auto |
spring- と spring- |
Rest(新) |
@Auto |
spring- |
@Mock/@Captor |
@Extend |
Mockito の JUnit 連携 |
| HtmlUnit の無効化 | @Auto |
同上 |
TestRestTemplate のために spring-boot-restclient を足すと、RestClient.Builder の自動構成も有効になる点が公式リファレンスに注記されています。新しく書くテストは RestTestClient を選ぶと依存が1つで済みます。
複数のテストで同じモックを使う場合は、@MockitoBean(types = {TaskService.class, MemberService.class}) のようにテストクラス(または自作アノテーション)へまとめて書けます。
3系の書き方を探すスクリプト
上の対応表を、プロジェクトのフォルダに対して機械的に当てるスクリプトです。標準ライブラリだけで動き、.java/.kt/pom.xml/build.gradle/.properties/.yml を調べます。YAML は入れ子のキーを a.b.c の形に直してから照合します。
#!/usr/bin/env python3
"""Spring Boot 3 の書き方が残っている箇所を探す(標準ライブラリのみ)。
使い方: python3 boot4_scan.py <プロジェクトのフォルダ>
見つかれば終了コード 1、なければ 0。"""
import re
import sys
from pathlib import Path
# (分類, 正規表現, 直し方)
RULES = [
("Jackson", r"\bcom\.fasterxml\.jackson\.(?!annotation\b)[\w.]+", "tools.jackson.… に変更(annotation だけは元のまま)"),
("Jackson", r"\bJackson2ObjectMapperBuilderCustomizer\b", "JsonMapperBuilderCustomizer"),
("Jackson", r"\bJsonObjectSerializer\b", "ObjectValueSerializer"),
("Jackson", r"\bJsonValueDeserializer\b", "ObjectValueDeserializer"),
("Jackson", r"@JsonComponent\b", "@JacksonComponent"),
("Jackson", r"@JsonMixin\b", "@JacksonMixin"),
("テスト", r"@MockBean\b", "@MockitoBean"),
("テスト", r"@SpyBean\b", "@MockitoSpyBean"),
("テスト", r"\bMockitoTestExecutionListener\b", "MockitoExtension を使う"),
("テスト", r"\borg\.springframework\.boot\.test\.web\.client\.TestRestTemplate\b",
"org.springframework.boot.resttestclient.TestRestTemplate"),
("テスト", r"\borg\.springframework\.boot\.test\.autoconfigure\.properties\.PropertyMapping\b",
"org.springframework.boot.test.context.PropertyMapping"),
("null注釈", r"\borg\.springframework\.lang\.(Nullable|NonNull)\b", "org.jspecify.annotations の注釈へ"),
("コード", r"\bimport\s+org\.springframework\.boot\.(?!persistence\.autoconfigure\.)[\w.]*\.EntityScan\b",
"org.springframework.boot.persistence.autoconfigure.EntityScan"),
("コード", r"\balwaysApplyingWhenNonNull\s*\(", "PropertyMapper の always() を検討"),
("コード", r"\bStreamBuilderFactoryBeanCustomizer\b", "StreamsBuilderFactoryBeanConfigurer"),
("コード", r"\bRabbitRetryTemplateCustomizer\b",
"RabbitTemplateRetrySettingsCustomizer / RabbitListenerRetrySettingsCustomizer"),
("コード", r"\bRestClientBuilderCustomizer\b", "Rest5ClientBuilderCustomizer(Elasticsearch)"),
("スターター", r"spring-boot-starter-web(?![\w-])", "spring-boot-starter-webmvc"),
("スターター", r"spring-boot-starter-web-services(?![\w-])", "spring-boot-starter-webservices"),
("スターター", r"spring-boot-starter-aop(?![\w-])", "spring-boot-starter-aspectj"),
("スターター", r"spring-boot-starter-oauth2-(client|resource-server|authorization-server)(?![\w-])",
"spring-boot-starter-security-oauth2-…"),
("スターター", r"spring-boot-starter-undertow(?![\w-])", "Tomcat か Jetty のスターターへ"),
("ビルド", r"\bhibernate-jpamodelgen\b", "hibernate-processor"),
("ビルド", r"loaderImplementation|LoaderImplementation\.CLASSIC", "設定ごと削除"),
("ビルド", r"jarmode=layertools", "jarmode=tools(4.1 で layertools は削除)"),
("設定", r"\bspring\.jackson\.(read|write)\.", "spring.jackson.json.read. / spring.jackson.json.write."),
("設定", r"\bspring\.jackson\.parser\.", "spring.jackson.json.read."),
("設定", r"\bspring\.session\.(redis|mongodb)\.", "spring.session.data.redis. / spring.session.data.mongodb."),
("設定", r"\bspring\.data\.mongodb\.(additional-hosts|authentication-database|database|host|password|port|"
r"protocol|replica-set-name|representation\.uuid|ssl\.|uri|username)", "spring.mongodb.…"),
("設定", r"\bspring\.dao\.exceptiontranslation\.enabled\b", "spring.persistence.exceptiontranslation.enabled"),
("設定", r"\bmanagement\.(health|metrics)\.mongo\.", "management.health.mongodb. / management.metrics.mongodb."),
("設定", r"\bspring\.kafka\.retry\.topic\.backoff\.random\b", "spring.kafka.retry.topic.backoff.jitter"),
]
RULES = [(kind, re.compile(pattern), fix) for kind, pattern, fix in RULES]
TARGETS = {".java", ".kt", ".groovy", ".xml", ".gradle", ".kts", ".properties", ".yml", ".yaml", ".factories"}
SKIP_DIRS = {".git", "target", "build", "node_modules", ".gradle", ".idea"}
def flatten_yaml(lines):
"""インデントをたどって YAML のキーを a.b.c 形式に直す(リストや複数行の値は対象外の簡易版)。"""
stack, out = [], []
for number, raw in enumerate(lines, 1):
match = re.match(r"^(\s*)([\w.-]+):", raw)
if not match or raw.lstrip().startswith("#"):
continue
indent = len(match.group(1))
while stack and stack[-1][0] >= indent:
stack.pop()
stack.append((indent, match.group(2)))
out.append((number, ".".join(key for _, key in stack) + "."))
return out
def scan(root):
hits = []
for path in sorted(root.rglob("*")):
if not path.is_file() or path.suffix not in TARGETS or SKIP_DIRS & set(path.parts):
continue
lines = path.read_text(encoding="utf-8", errors="replace").splitlines()
rows = flatten_yaml(lines) if path.suffix in {".yml", ".yaml"} else list(enumerate(lines, 1))
seen = set() # YAML は親キーと子キーで同じ指摘が重なるので 1 回にまとめる
for number, text in rows:
for kind, regex, fix in RULES:
found = regex.search(text)
if found and (path, found.group(0)) not in seen:
seen.add((path, found.group(0)) if path.suffix in {".yml", ".yaml"} else (path, number, kind, fix))
hits.append((kind, path.relative_to(root), number, found.group(0), fix))
# ファイルをまたいで判断するもの:Flyway・Liquibase を使っているのに専用スターターが無い
build_text = "\n".join(p.read_text(encoding="utf-8", errors="replace")
for p in root.rglob("*") if p.name in {"pom.xml", "build.gradle", "build.gradle.kts"})
for lib, starter in (("flyway-core", "spring-boot-starter-flyway"), ("liquibase-core", "spring-boot-starter-liquibase")):
if lib in build_text and starter not in build_text:
hits.append(("スターター", Path("(ビルド定義)"), 0, lib, starter + " を追加"))
return hits
def main():
root = Path(sys.argv[1] if len(sys.argv) > 1 else ".")
hits = scan(root)
for kind, path, number, found, fix in hits:
print(f"[{kind}] {path}:{number} {found} -> {fix}")
counts = {}
for kind, *_ in hits:
counts[kind] = counts.get(kind, 0) + 1
print("-" * 60)
print("合計", len(hits), "件", " ".join(f"{k}={v}" for k, v in counts.items()))
sys.exit(1 if hits else 0)
if __name__ == "__main__":
main()
3.5 の書き方が残っている小さなサンプル(pom.xml、設定クラス、application.yml、テスト各1ファイル)に対して実行した結果です。
$ python3 tools/boot4_scan.py sample
[スターター] pom.xml:10 spring-boot-starter-web -> spring-boot-starter-webmvc
[スターター] pom.xml:14 spring-boot-starter-aop -> spring-boot-starter-aspectj
[Jackson] src/main/java/com/example/demo/JsonConfig.java:4 com.fasterxml.jackson.databind.SerializationFeature -> tools.jackson.… に変更(annotation だけは元のまま)
[Jackson] src/main/java/com/example/demo/JsonConfig.java:5 Jackson2ObjectMapperBuilderCustomizer -> JsonMapperBuilderCustomizer
[null注釈] src/main/java/com/example/demo/JsonConfig.java:8 org.springframework.lang.Nullable -> org.jspecify.annotations の注釈へ
[Jackson] src/main/java/com/example/demo/JsonConfig.java:13 Jackson2ObjectMapperBuilderCustomizer -> JsonMapperBuilderCustomizer
[設定] src/main/resources/application.yml:3 spring.jackson.write. -> spring.jackson.json.read. / spring.jackson.json.write.
[設定] src/main/resources/application.yml:6 spring.session.redis. -> spring.session.data.redis. / spring.session.data.mongodb.
[設定] src/main/resources/application.yml:10 spring.dao.exceptiontranslation.enabled -> spring.persistence.exceptiontranslation.enabled
[テスト] src/test/java/com/example/demo/TaskControllerTest.java:5 org.springframework.boot.test.web.client.TestRestTemplate -> org.springframework.boot.resttestclient.TestRestTemplate
[テスト] src/test/java/com/example/demo/TaskControllerTest.java:9 @MockBean -> @MockitoBean
[スターター] (ビルド定義):0 flyway-core -> spring-boot-starter-flyway を追加
------------------------------------------------------------
合計 12 件 スターター=3 Jackson=3 null注釈=1 設定=3 テスト=2
$ echo $?
1
pom.xml に flyway-core があるのに spring-boot-starter-flyway が無い、というファイルをまたいだ指摘も最後に出ています。終了コードは見つかれば 1、無ければ 0 なので、CI に入れておくと、移行後に 3 系の書き方が戻ってきたときに検知できます。
スクリプトを置かずに手早く見たいときは、grep でも主なものは拾えます。同じサンプルでの実行結果です。
$ grep -rnE 'com\.fasterxml\.jackson\.(databind|core|datatype|dataformat|module)|@MockBean|@SpyBean|spring-boot-starter-(web|aop)<' sample
sample/src/test/java/com/example/demo/TaskControllerTest.java:9: @MockBean
sample/src/main/java/com/example/demo/JsonConfig.java:4:import com.fasterxml.jackson.databind.SerializationFeature;
sample/pom.xml:10: <artifactId>spring-boot-starter-web</artifactId>
sample/pom.xml:14: <artifactId>spring-boot-starter-aop</artifactId>
コピペ用の移行チェックリスト
Issue やプルリクエストの説明にそのまま貼れる形です。該当しない行は消して使ってください。
# Spring Boot 4 移行チェックリスト
## 0. 準備
- [ ] 現在の版と行き先の版を決めた(例:3.5.x → 4.1.1)
- [ ] Java 17 以上で動いている(jOOQ を使うなら 21 以上)
- [ ] 依存ライブラリ(Spring Cloud など)の 4 系対応版を確認した
- [ ] 移行用のブランチを切り、CI が通る状態から始めた
## 1. 3.5 系の最新版へ
- [ ] spring-boot の版を 3.5 系の最新に上げた
- [ ] ビルドと全テストが通る
## 2. 非推奨の解消
- [ ] -Xlint:deprecation を有効にして警告を一覧にした
- [ ] 非推奨のクラス・メソッド・プロパティを置き換えた
- [ ] spring-boot-properties-migrator を一時的に追加した
## 3. classic スターターで 4 へ
- [ ] spring-boot の版を 4.1.1 にした
- [ ] spring-boot-starter → spring-boot-starter-classic
- [ ] spring-boot-starter-test → spring-boot-starter-test-classic
- [ ] Undertow を使っていれば Tomcat か Jetty に替えた
- [ ] loaderImplementation(CLASSIC)の設定を削除した
- [ ] コンパイルが通る
## 4. スターターを個別に置き換え
- [ ] spring-boot-starter-web → spring-boot-starter-webmvc
- [ ] spring-boot-starter-aop → spring-boot-starter-aspectj
- [ ] oauth2 系 → spring-boot-starter-security-oauth2-…
- [ ] Flyway/Liquibase 用のスターターを追加した
- [ ] Spring Batch のメタデータ保存先を確認した(DB なら -batch-jdbc)
- [ ] 技術ごとの -test スターターを追加した
- [ ] classic スターターを外しても起動する
## 5. Jackson 3
- [ ] import を com.fasterxml.jackson → tools.jackson に変更(annotation は除く)
- [ ] Jackson2ObjectMapperBuilderCustomizer → JsonMapperBuilderCustomizer
- [ ] @JsonComponent/@JsonMixin → @JacksonComponent/@JacksonMixin
- [ ] spring.jackson.read/write/parser → spring.jackson.json.read/write
- [ ] JSON の入出力(日付・null・数値)を確かめるテストが通る
- [ ] 橋渡し(use-jackson2-defaults/spring-boot-jackson2)を使った場合は外す予定を決めた
## 6. テスト
- [ ] @MockBean/@SpyBean → @MockitoBean/@MockitoSpyBean
- [ ] MockMvc を使うテストに @AutoConfigureMockMvc を付けた
- [ ] TestRestTemplate を使うテストに @AutoConfigureTestRestTemplate を付けた
- [ ] @Mock/@Captor のテストに MockitoExtension を付けた
- [ ] 全テストが通る
## 7. 黙って変わる点の確認
- [ ] /actuator/health に liveness/readiness が出てよいか
- [ ] ログファイルの文字コード(UTF-8)
- [ ] 設定キーの名前変更(Session・MongoDB・Kafka・persistence)
- [ ] DevTools のライブリロードの要否
- [ ] Maven の optional 依存が JAR に必要か
- [ ] Dockerfile の jarmode=layertools → jarmode=tools
## 8. 仕上げ
- [ ] spring-boot-properties-migrator を外した
- [ ] 3 系の書き方の検出スクリプトが 0 件
- [ ] 関連ライブラリのリリースノートを確認した(Framework 7.0/Security 7.0/Data 2025.1 など)
よくあるつまずきと直し方
| 症状 | 原因 | 直し方 |
|---|---|---|
com. が見つからない |
Jackson 3 でパッケージが変わった | tools. に直す |
@Mock が見つからない |
4.0 で削除 | @Mockito に直す |
Mock を注入できない |
@Spring が自動構成しなくなった |
@Auto を付ける |
| マイグレーションが走らずテーブルが無い | Flyway 用スターターが無い | spring- を足す |
| バッチの履歴が DB に残らない | spring- がメモリ動作になった |
spring- に替える |
| 設定を書いたのに効かない | キーの名前が変わった | properties-migrator で診断し、対応表で直す |
@Nullable を付けた Actuator の引数が必須扱いになる |
org. が対象外 |
org. に直す |
よくある質問
Q. 3.5 を飛ばして、3.4 以前から直接 4 に上げられますか? A. 公式移行ガイドは、先に 3.5 系の最新版へ上げて非推奨の呼び出しを見直すことを最初の手順にしています。3 系で非推奨だったものは 4.0 で削除されているため、3.5 で警告を消しておくほうが、4 に上げたあとのエラーが少なく済みます。
Q. classic スターターはいつまで使えますか? A. 公式は「早く動かしたいときの手段」と位置づけ、最終的には classic から離れることを勧めています。期限は移行ガイドに書かれていないので、技術ごとのスターターへの置き換えまでを移行の完了条件にしておくと安心です。
Q. Jackson 2 のまま 4 に上げることはできますか?
A. spring-boot-jackson2 モジュールを追加すると Jackson 2 の ObjectMapper が自動構成されます。ただし非推奨の形での提供で、将来のリリースで削除される予定と明記されています。Jackson 3 を使いつつ既定値だけ 2 に近づける spring.jackson.use-jackson2-defaults=true もあります。
Q. 4.0 と 4.1 のどちらを目指すのがよいですか?
A. 4.0系の OSS サポートは 2026年12月31日までなので、これから上げるなら 4.1系(2027年7月31日まで)が候補になります。4.0 から 4.1 への変更は、4.0 で非推奨だったものの削除と layertools の削除などに限られます。
まとめ
- 移行は6段階:3.5 最新化 → 非推奨の解消 → classic スターターで 4 へ → スターター個別化 → Jackson 3 → テスト。
- 行き先は 4.1系:3.5系の OSS サポートは 2026-06-30 に終了、4.0系は 2026-12-31 まで、4.1系は 2027-07-31 まで。
- コンパイルで分かる変更(パッケージ名、
@MockBean、Undertow)は、エラーを順に直せば進む。 - 黙って変わる変更(Flyway/Liquibase のスターター、Spring Batch の保存先、設定キーの名前変更、liveness/readiness)は、先に確認用のテストを用意する。
- Jackson 3 は
tools.jackson。jackson-annotationsだけはcom.fasterxml.jackson.annotationのまま。 - テストは明示する:
@AutoConfigureMockMvc、@AutoConfigureTestRestTemplate、@MockitoBean。 - 検出スクリプトとチェックリストを CI とプルリクエストに置くと、直し漏れを減らせる。
参考・出典
確認日はいずれも 2026年10月7日です。
- Spring Boot 4.0 Migration Guide: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.0-Migration-Guide
- Spring Boot 4.1 Release Notes: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-4.1-Release-Notes
- Spring Boot プロジェクトページ(現行 4.1.1): https://spring.io/projects/spring-boot
- 世代別サポート期間: https://api.spring.io/projects/spring-boot/generations
- Supported Versions(サポート方針): https://github.com/spring-projects/spring-boot/wiki/Supported-Versions
- MockBean API(3.5.16、非推奨の注記): https://docs.spring.io/spring-boot/3.5/api/java/org/springframework/boot/test/mock/mockito/MockBean.html
- Testing Spring Boot Applications(4.1.1): https://docs.spring.io/spring-boot/reference/testing/spring-boot-applications.html
- JSON(4.1.1): https://docs.spring.io/spring-boot/reference/features/json.html
- Customize the Jackson JsonMapper(4.1.1): https://docs.spring.io/spring-boot/how-to/spring-mvc.html
- JsonMapperBuilderCustomizer API(4.1.1): https://docs.spring.io/spring-boot/4.1.1/api/java/org/springframework/boot/jackson/autoconfigure/JsonMapperBuilderCustomizer.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Spring Boot 4移行の手順|3から4の変更点一覧とチェックリスト」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。