SpringBoot 3.0がGAとなりました。
Release Noteを参考に2.7系からの変更点をまとめます。
自分が移行するときに関係のあるものや興味があるものが中心となりますがご容赦ください🙇♂️
また、ビルドツールはgradleを前提にまとめます。
mavenユーザの方は、方向性だけ参考にしていただけると幸いです🙇♂️
移行方法
メジャーバージョンのアップデートということで、Migration Guideが用意されています。
基本的には以下の記事の共通タスクを実行すれば良いです。
これ以外の対応をまとめます。

一部の作業は自動化が可能です!
自動化の方法は以下の記事でまとめているので合わせてご覧ください!
依存ライブラリのバージョンを確認
SpringBootのバージョンに依存するライブラリを使っている場合、
そのライブラリでSpringBoot3.0に対応したバージョンも確認しておきます。
自分の周りで関係があるものだけ整理しておきます。
| ライブラリ | SpringBoot3.0対応バージョン | 参考リンク |
|---|---|---|
| spring-cloud系 | 2022.0.x | https://spring.io/projects/spring-cloud |
| mybatis-spring-boot-starter | 3.0 | http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/#requirements |
Javaを17以降に更新する
SpringBoot3.0ではJava17以降のバージョンが必要です。
19もサポートされてはいますがLTSなのは17なので、
17に更新をしておくのが無難かと思います。
javax → jakartaへパッケージを変更
javaxパッケージで定義されていたアノテーション(例えば @PostConstructとか@Entityとか@Maxとか)をjakartaパッケージのものに書き換える必要があります。
明示的にjavaxのライブラリを依存に追加していない場合は、コンパイルエラーになるはずなので、気づけます。
普通にアプリケーションは起動するのに実際は期待通りに動いてなんてこともありえます。
// 変更後
import jakarta.annotation.PostConstruct;
// 変更前
// import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;
@Component
public class Sample {
@PostConstruct
void init() {
// something to do
}
}また、javax系のライブラリを裏で使っているライブラリがないか気になる場合は以下のコマンドで調べることができます。
./gradlew dependencyInsight --dependency javax共通的に移行が必要な内容は以上です!
ここからは変更点を整理していきます。
ログの日付フォーマット
ログの日付のデフォルトがyyyy-MM-dd HH:mm:ss.SSSからyyyy-MM-dd’T’HH:mm:ss.SSSXXXに変更されました。
logback.xmlや環境変数でフォーマットを指定していない限りこの影響を受けるかと。
特にログをパースして集計するような仕組みを構築している場合、この影響をもろに食らうかもしれません。
環境変数LOG_DATEFORMAT_PATTERNやプロパティlogging.pattern.dateformatにyyyy-MM-dd HH:mm:ss.SSSを指定することでこの変更の影響をなくせます。
spring.factoryからEnableAutoConfigurationが廃止
SpringBoot2.7からorg.springframework.boot.autoconfigure.AutoConfiguration.importsでAutoConfigurationクラスを定義できるようになっていたようで、
3.0でそちらを利用する必要があります。以下書き換え例です。
Before
META-INF/spring.factoriesに以下のような記述をしていると思います。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
rhirabay.lib.SampleAutoConfigurationAfter
クラス名の部分だけMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importsにコピペします。
※複数ある場合は改行で列挙すればOK
rhirabay.lib.SampleAutoConfigurationURLのマッチング
WebMVC・WebFluxともにURLの最後の/の扱いが変わります。
これまでは/sampleと指定していれば/sample, /sample/どちらでもアクセスができましたが、
SpringBoot3.0からは/sampleのみしかアクセスできず、これまでと同じ動作をさせたければ明示的な指定が必要です。
// 変更前
// @GetMapping("/sample")
// 変更後
@GetMapping("/sample", "/sample/")一括で設定を元に戻したい場合は以下のようなConfigurationクラスを定義すればよいです。
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch(true);
}
}ただ、setUseTrailingSlashMatchが非推奨なメソッドなので互換性を担保したいのであればURLを2つ指定する方針が良いのかなーと
Jettyがサポート外に
もし使用したい場合はServlet APIを5.0にダウングレードする必要があります。jakarta.servlet.versionを指定すればOKです。
※Release Noteではjakarta-servlet.versionで紹介されていたので今後変わるかも、、、
ext {
set('jakarta.servlet.version', "5.0")
}Actuatorの情報をサニタイズ(/env, /configprops)
Actuatorの/env, /configpropsの2つのエンドポイントについて値がマスキングされるようになりました。
これまではパスワード等の機密情報もそのまま表示されてしまっていたのでセキュリティ的に良くなかったものを改善した形です。
もし開発環境だけ値を確認したいとかであれば、management.endpoint.env.show-valuesやmanagement.endpoint.configprops.show-valuesをALWAYSやWHEN_AUTHORIZEDに設定すればよいようです。
メトリクスの収集方法が変更に
メトリクスの収集に関するクラスが調整されています。
http_server_request系のメトリクスのタグの生成ロジックに手を入れていたり、TagProviderとかWebMvcMetricsFilterとかをカスタマイズしている場合は、ServerHttpObservationFilterへの移行が必要なようです。
また、HTTP Client側でspring-boot-actuatorが提供する MetricsWebClientCustomizerやMetricsRestTemplateCustomizerを使用している場合は、ObservationWebClientCustomizerやObservationRestTemplateCustomizerに切り替える必要があります。
mainクラスの指定方法
これまでbootJarやbootRunでmainクラスを指定していた場合は変更が必要です。
springBoot {
mainClass = "com.example.Application"
}RestTemplateで使用するHttpClient
これまでHttpClient4に依存していましたが、HttpClient5への依存に切り替わりました。
使用するHttpClientをカスタイマイズしていた場合、HttpCliet5の利用に切り替える必要があります。
dependencies {
// 変更前
// implementation 'org.apache.httpcomponents:httpclient'
// 変更後
implementation 'org.apache.httpcomponents.client5:httpclient5'
}実装の変更点についてはimportするパッケージが変わるのと一部クラスがbuilderパターンで生成することが推奨されているのを把握しておけば良さそうかなと
// httpclient4
// import org.apache.http.client.HttpClient;
// httpclient5
import org.apache.hc.client5.http.classic.HttpClient; // PoolingHttpClientConnectionManager
// httpclient4
// PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
// connectionManager.setMaxTotal(10);
// httpclient5(builderパターンで生成)
PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
.setMaxConnTotal(10)
.build(); // httpclient4
// SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(SSLContext.getInstance("TLSv1.2"));
// httpclient5
SSLConnectionSocketFactory socketFactory = SSLConnectionSocketFactoryBuilder.create()
.setTlsVersions(TLS.V_1_2)
.build();※公式のMigrationGuideはこちらです!

