LoginSignup
2
2

More than 3 years have passed since last update.

Spring Boot 2.0からSpring Boot 2.2にマイグレーションしたときの変更点

Posted at

はじめに

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では管理下になったため、バージョンの指定が不要となりました。

SpringBoot2.0
<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>
SpringBoot2.2
<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 プロパティを設定してください。

SpringBoot2.0
spring:
  main:
    allow-bean-definition-overriding: true

RestTemplateBuilderの設定値の型変更

RestTemplateBuilderを用いてRestTemplateの設定を行う際、タイムアウトの設定がミリ秒指定から java.time.Duration 指定に変更となり、単位がわかりやすくなりました。

SpringBoot1.5
new RestTemplateBuilder()
    .setConnectTimeout(5000)
    .setReadTimeout(60000);
SpringBoot2.0
new RestTemplateBuilder()
    .setConnectTimeout(Duration.ofMillis(5000))
    .setReadTimeout(Duration.ofMillis(60000));

Sortオブジェクトの生成方法変更

Spring Dataの org.springframework.data.domain.Sort オブジェクトの生成方法が、 new から by に変わりました。

SpringBoot1.5
new Sort(Sort.Direction.fromString(sortDirection), sortColumn);
SpringBoot2.0
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にバージョンアップしたときに比べればかなり楽でしたが、それでもちょくちょく細かな破壊的修正が加わっているため、注意が必要です。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2