当谈到从Spring Boot 1.5升级至2.1时的经历

首先

由于Spring Boot 1.x系列将于2019年8月1日结束维护,因此我迫不得已将Spring Boot版本从1.5.2升级到2.1.5。以下是我在升级过程中所做的笔记。

主要的构成

    • Java 8

 

    • Gradle 4.10.3

 

    • Web、バッチ両方ありの巨大なマルチプロジェクト

Springアプリケーション5個
プレーンなJavaアプリケーション1個
ライブラリ系のモジュール6個

MySQL
Flyway
JOOQ
Thymeleaf

做过的事情 (zuò guò de shì

收集情报

↓的公式迁移指南中记录了基本的迁移方法和注意事项。
Spring Boot 2.0 迁移指南

在操作过程中,我一边阅读公式迁移指南,一边通过搜索解决了一些不明确或遇到困难的问题。此外,对于主要库的重要版本更改,我会查看发布说明,以确保没有破坏性改动。

1. 首先将spring-boot-properties-migrator添加到项目依赖中(*在迁移完成后移除*)。

在Spring Boot 2中,一些在application.properties/application.yml中定义的属性的键和配置内容已经发生了变化。
如果将spring-boot-properties-migrator添加到依赖项中,那么在应用启动时,如果存在配置内容仍然保持旧状态的属性,它会生成警告日志。同时,它还会暂时允许使用旧属性的写法来确保应用的正常运行。

在dependencies中添加以下行。(完成迁移后删除)。

runtime "org.springframework.boot:spring-boot-properties-migrator"

2. 添加Gradle的依赖管理插件。

在1.x版本中,Spring Boot插件中包含了Dependency Management插件,但从2.x版本开始,Dependency Management插件似乎已经分离出来
在build.gradle文件中添加Dependency Management插件。

  apply plugin: 'org.springframework.boot'
+ apply plugin: 'io.spring.dependency-management' // <-- コレを追加

将Spring Boot的版本升级

  etx {
-   springBootVersion = '1.5.2.RELEASE'
+   springBootVersion = '2.1.5.RELEASE'
  }

升级Spring Boot版本会自动升级各种库的版本。

这次的主要变化

    • Spring (4→5)

 

    • Thymeleaf (2→3)

 

    • MySQLのJDBCドライバー (5.1→8.0)

 

    • Flyway (4→5)

 

    JOOQ (3.9→3.11)

此外,RDB的连接池库已从Tomcat JDBC更换至HikariCP。

※ 每个库的具体版本号可以在spring-boot-dependencies的POM文件中找到。

4. Spring Boot的配置

4.1. Gradle配置

bootRepackage这个任务消失了,换成了名为bootJar的任务。

bootJar {
  mainClassName = 'foo.bar.App'
  launchScript()                // <-- bootRapackageで`executable = true`を設定していた場合、これがその代わりになる
}

修正绑定属性时的键名。

如果在Java中使用@ConfigurationProperties 或者@Value将Spring Boot的属性绑定到Java中,需要统一属性名称的写法为“Canonical”。详细请参考Spring Boot 2.0 Canonical Properties。

基本上,全部改成小写字母,删除”-“和”_”就可以了。

- @ConfigurationProperties(prefix = "foo-bar.apiKey")
+ @ConfigurationProperties(prefix = "foobar.apikey")

5. 春季网络MVC

5.1. WebMvcConfigurerAdapter转变为WebMvcConfigurer.

WebMvcConfigurerAdapter类已被废弃,已改为使用WebMvcConfigurer接口。


- public class WebMvcConfig extends WebMvcConfigurerAdapter {
+ public class WebMvcConfig implements WebMvcConfigurer {

5.2版本的控制器无法自动映射带有文件扩展名的URL。

@GetMapping("/users")
public List<Users> listUsers() {

我们之前准备了类似的端点,并且前端通过”GET /users.json”的路径进行访问。但是现在不能这样做了。
现在只需要普通地通过”GET /users”进行访问即可,所以我将”.json”全部删除了。

6. MySQL

5.1变为8.0。

6.1. 修改MySQL驱动器的类名。

我找到了com.mysql.jdbc.Driver的部分,并将其替换为com.mysql.cj.jdbc.Driver。

7. JOOQ 只需要一个选项, 请用中文将以下内容改述一遍:

3.9→3.11表示正在进行中。
由于jOOQ版本更新,进行了一些修正。
建议阅读jOOQ发布说明历史中的Breaking changes部分。

升级JOOG的Gradle插件版本为7.1。

从JOOQ3.11.x版本开始,需要使用gradle-jooq-plugin3.x插件。

 plugins {
-  id 'nu.studer.jooq' version '2.0.11'
+  id 'nu.studer.jooq' version '3.0.3'
 }

7.2. 修正Gradle设置以生成JOOQ代码

由于API包的名称已更改,因此需要进行修正。

  mainDb(sourceSets.main) {
    jdbc {
      ...
    }
    generator {
-     name = 'org.jooq.util.DefaultGenerator'
+     name = 'org.jooq.codegen.DefaultGenerator'
      ...
      database {
-       name = 'org.jooq.util.mysql.MySQLDatabase'
+       name = 'org.jooq.meta.mysql.MySQLDatabase'
        ...

重新生成JOQQ

Alternatively:
重新生成JOQQ的生成

重新生成代码

由于7.4版本中Cursor#fetchOne()方法被标记为不推荐使用,所以需要进行修正。

 while (cursor.hasNext()) 
-  Record record = cursor.fetchOne();
+  Record record = cursor.fetchNext();

8. 飞行之路 zhī lù)

如果从3系转移到5系,则需要先转移到4系。

8.1. 更改属性名称

application.properties / application.yml 的属性名称已经从 flyway.* 变为 spring.flyway.*。

- flyway:
-   enabled: true
+ spring:
+   flyway:
+     enabled: true

设定迁移执行历史管理表的名称。

在Flyway的3系和4系中,执行历史记录通过一个名为schema_version的表进行管理。然而,在5系中,该表的名字改为了flyway_schema_history。如果要继续使用schema_version表,需要在application.properties或application.yml文件中设置一个名为spring.flyway.table的属性。

spring:
  flyway:
    table: schema_version

此外,如果您正在使用Gradle的Flyway插件,也需要在那里进行相应配置。

flyway {
  ...
  table = 'schema_version'
}

9. Thymeleaf: 西洋芹

9.1.修复依赖库

- implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity4'
+ implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity5' // <--- Spring SecurityのDialectのバージョンアップ

修正模板布局的描述方法

Thymeleaf3 的布局语法发生了变化。
参考:

    • https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.0-Migration-Guide#template-engines

 

    https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#template-layout

受限于时间和空间的限制,我们只需要一种选择,原句表述如下:

排版
  <!DOCTYPE html>
  <html lang="ja"
        xmlns:th="http://www.thymeleaf.org"
        xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
  <head>
    <meta charset="utf-8"/>
    <!-- 「{各ページのタイトル} | アプリ名」のようなtitleになる -->
-   <title layout:title-pattern="$CONTENT_TITLE | $DECORATOR_TITLE">アプリ名</title>
+   <title layout:title-pattern="$CONTENT_TITLE | $LAYOUT_TITLE">アプリ名</title>
    ...
  </head>
  <body>
    <!-- 共通のHTMLを埋め込む -->
-   <div layout:replace="common/header::partial"></div>
+   <div layout:replace="~{common/header::partial}"></div>

    <!-- 各ページのコンテンツをここに展開 -->
    <div layout:fragment="content"></div>
  </bod>
  </html>
单独页面
  <!DOCTYPE html>
  <html
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      xmlns:th="http://www.springframework.org/schema/mvc"
-     layout:decorator="layout/default">
+     layout:decorate="~{layout/default}">
  <head>
    <title>各ページのタイトル</title>
  </head>
  <body>
    <!-- 各ページのコンテンツ -->
    <div layout:fragment="content">
      Hello World
    </div>
  </body>
  </html>

10. 连接池

由于Tomcat JDBC已更改为HikariCP,因此需要修改配置内容。

属性名称将从spring.datasource.tomcat.*更改为spring.datasource.hikari.*。

HikariCP可以通过com.zaxxer.hikari.HikariConfig中的定义进行配置。

故障排除

生成Jar文件时不包含前端构建内容

最初就在Gradle中定义了用于构建前端的任务,并设置在创建jar文件时执行。

jar.dependsOn compileFrontend

但是,从Spring Boot 2版本开始,我们开始使用bootJar任务来生成jar包,所以进行了如下修改。

bootJar.dependsOn compileFrontend

DBUnit在MySQL上崩溃了。

org.dbunit.database.AmbiguousTableNameException: ACCOUNTS

当多个数据库中存在同名表时,似乎会出现错误。当在JDBC的URL中添加了nullCatalogMeansCurrent=true查询参数后,问题得到解决。(这似乎是MySQL的JDBC驱动程序的默认行为发生了变化)

当使用JOOQ对TINYINT(1)字段进行SELECT时会出错。

java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.Byte

在使用JOOb进行开发时,我们的策略是将BIT(1)映射为Boolean,而将TINYINT(1)映射为Byte。然而,在更新到Spring Boot 2之后,TINYINT(1)被错误地映射为Boolean,导致了ClassCastException的发生。

当我在JDBC的URL中添加了查询参数”tinyInt1isBit=false”后问题得到解决。
据说MySQL的JDBC驱动在内部将TINYINT(1)作为BIT(1)处理,导致其变成了布尔类型。

如果一个WEB域名中包含下划线(_),则会出现IllegalArgumentException异常。

java.lang.IllegalArgumentException: The character [_] is never valid in a domain name.

Tomcat的版本升级后,似乎无法接受包含“_”的域名。
(根据RFC的规定,域名中包含“_”是不正确的。)
→由于子域名中包含“_”,所以我们更改了子域名以进行适应。

请参考以下链接:https://stackoverflow.com/questions/53504857/在域名中,该字符永远无效。

广告
将在 10 秒后关闭
bannerAds