SpringBoot 3.0がGAとなりました。
Release Noteを参考に2.7系からの変更点をまとめます。
自分が移行するときに関係のあるものや興味があるものが中心となりますがご容赦ください🙇♂️
また、ビルドツールはgradleを前提にまとめます。
mavenユーザの方は、方向性だけ参考にしていただけると幸いです🙇♂️
移行方法
メジャーバージョンのアップデートということで、Migration Guideが用意されています。
基本的には以下の記事の共通タスクを実行すれば良いです。
SpringBoot Updateまとめこれ以外の対応をまとめます。
一部の作業は自動化が可能です!
自動化の方法は以下の記事でまとめているので合わせてご覧ください!
依存ライブラリのバージョンを確認
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.SampleAutoConfiguration
After
クラス名の部分だけMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
にコピペします。
※複数ある場合は改行で列挙すればOK
rhirabay.lib.SampleAutoConfiguration
URLのマッチング
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はこちらです!