はじめに
Spring Boot 2.0.2のアプリケーション(約7KL、SPAのサーバ部分)をSpring Boot 2.2.5にマイグレーションしてみたときの修正ポイントを書いておきます。
Spring Bootの修正箇所
Maven
JUnit5を使用していたのですが、Spring Boot 2.0ではspring-boot-starter-parentの管理下ではなかったjunit-platform-launcherとmockito-junit-jupiterが、Spring Boot 2.2では管理下になったため、バージョンの指定が不要となりました。
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.3.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.22.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
Beanの上書き設定
Spring Boot 2.0では、同じBeanの定義があったときに、 @Primary
を付与したBeanが優先されましたが、Spring Boot 2.2では初期化時にBeanDefinitionOverrideException例外が発生します。
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'taskExecutor' defined in mypackage.TestConfiguration: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=true; factoryBeanName=testConfiguration; factoryMethodName=taskExecutor; initMethodName=null; destroyMethodName=(inferred); defined in mypackage.TestConfiguration] for bean 'taskExecutor': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=mainConfig; factoryMethodName=taskExecutor; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [mypackage/MainConfig.class]] bound.
これを回避するには、application.ymlに spring.main.allow-bean-definition-overriding
プロパティを設定してください。
spring:
main:
allow-bean-definition-overriding: true
RestTemplateBuilderの設定値の型変更
RestTemplateBuilderを用いてRestTemplateの設定を行う際、タイムアウトの設定がミリ秒指定から java.time.Duration
指定に変更となり、単位がわかりやすくなりました。
new RestTemplateBuilder()
.setConnectTimeout(5000)
.setReadTimeout(60000);
new RestTemplateBuilder()
.setConnectTimeout(Duration.ofMillis(5000))
.setReadTimeout(Duration.ofMillis(60000));
Sortオブジェクトの生成方法変更
Spring Dataの org.springframework.data.domain.Sort
オブジェクトの生成方法が、 new
から by
に変わりました。
new Sort(Sort.Direction.fromString(sortDirection), sortColumn);
Sort.by(Sort.Direction.fromString(sortDirection), sortColumn);
securityパッケージ配下のさらにservletパッケージの中に移動したようです。
その他
これは元から実装が悪かったのですが、JPAのリポジトリインタフェースのメソッドに
List<Auth> findByRoleContains(Collection<Role> roles);
という定義があり、使っていませんでした。
Spring Boot 2.2に変更してアプリを起動すると、
Caused by: java.lang.IllegalStateException: Operator CONTAINING on role requires a scalar argument, found interface java.util.Collection in method public abstract java.util.List mypackage.repository.AuthRepository.findByRoleContains(java.util.Collection).
の例外が発生しました。
Containsは文字列を含む検索であり、本来はContainsではなくInを使うべき箇所なのですが。なぜ今まで問題なかったのか。。(この使っていなかったから気づかなかった)
List<Auth> findByRoleIn(Collection<Role> roles);
まとめ
Spring Boot 1.5から2.0にバージョンアップしたときに比べればかなり楽でしたが、それでもちょくちょく細かな破壊的修正が加わっているため、注意が必要です。