Spring Boot 2.0 升級指南

来源:https://www.cnblogs.com/janlle/archive/2019/04/20/10741387.html
-Advertisement-
Play Games

Spring Boot 2.0 升級指南 前言 Spring Boot已經發佈2.0有5個月多,多了很多新特性,一些坑也慢慢被填上,最近有空,就把項目中Spring Boot 版本做了升級,順便整理下升級的時候遇到的一些坑,做個記錄。後續的教程就以最新的2.03版本為主。參考官方文檔翻譯 在你開始之 ...


Spring Boot 2.0 升級指南

前言

Spring Boot已經發佈2.0有5個月多,多了很多新特性,一些坑也慢慢被填上,最近有空,就把項目中Spring Boot 版本做了升級,順便整理下升級的時候遇到的一些坑,做個記錄。後續的教程就以最新的2.03版本為主。參考官方文檔翻譯

在你開始之前

  • 2.x 至少需要 JDK 8 的支持,2.x 裡面的許多方法應用了 JDK 8 的許多高級新特性,所以你要升級到 2.0 版本,先確認你的應用必須相容 JDK 8。
    另外,2.x 開始了對 JDK 9 的支持。

  • 2.x 對第三方類庫升級了所有能升級的穩定版本,一些值得關註的類庫升級我給列出來了。

    1.Spring Framework 5+
    2.Tomcat 8.5+
    3.Flyway 5+
    4.Hibernate 5.2+
    5.Thymeleaf 3+

在 Spring Boot 2.0 中,許多配置屬性被重新命名/刪除,開發人員需要更新application.properties/ application.yml相應的配置。為了幫助你解決這一問題,Spring Boot 發佈了一個新spring-boot-properties-migrator模塊。一旦作為該模塊作為依賴被添加到你的項目中,它不僅會分析應用程式的環境,而且還會在啟動時列印診斷信息,而且還會在運行時為您暫時遷移屬性。在您的應用程式遷移期間,這個模塊是必備的:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-properties-migrator</artifactId>
</dependency>

註意:遷移完成之後,請確保從項目的依賴關係中移除該模塊。

構建您的 Spring Boot 應用程式

Spring Boot Maven 插件
為了保持了一致性,並且避免與其他插件發生衝突,現在暴露的插件配置屬性都以一個spring-boot首碼開始。

例如,以下命令prod使用命令行啟用配置文件

mvn spring-boot:run -Dspring-boot.run.profiles=prod

Spring Boot 新特性,預設動態代理策略

Spring Boot現在預設使用CGLIB動態代理(基於類的動態代理), 包括AOP. 如果需要基於介面的動態代理(JDK基於介面的動態代理) , 需要設置spring.aop.proxy-target-class屬性為false.

開發 Web 應用程式嵌入式容器包裝結構

為了支持響應式用例,嵌入式容器包結構已經被大幅度的重構。 EmbeddedServletContainer已被重新命名為,WebServer並且該org.springframework.boot.context.embedded包已被重新定位到org.springframework.boot.web.embedded。例如,如果您使用TomcatEmbeddedServletContainerFactory回調介面定製嵌入式 Tomcat 容器,則應該使用TomcatServletWebServerFactory。

特定於 Servlet 的伺服器屬性
許多server.* 屬性 ( Servlet 特有的) 已經轉移到server.servlet:

舊的屬性 新的屬性
server.context-parameters.* server.servlet.context-parameters.*
server.context-path server.servlet.context-path
server.jsp.class-name server.servlet.jsp.class-name
server.jsp.init-parameters.* server.servlet.jsp.init-parameters.*
server.jsp.registered server.servlet.jsp.registered
server.servlet-path server.servlet.path

模板引擎

Mustache模板預設的文件擴展名

Mustache模板的文件擴展名曾經是.html。現在的擴展名為.mustache,與官方規格和大多數的IDE插件保持一致。你可以通過更改spring.mustache.suffix配置文件的configuration key來重寫這個新的預設值。

Jackson/JSON支持

在2.0版本,我們已經設置Jackson配置文件的預設值,將ISO-8601 strings寫作了JSR-310。如果你希望返回之前的設置,可以添加spring.jackson.serialization.write-dates-as-timestamps=true 到你的配置文件中。

一個新的spring-boot-starter-json starter收集了必要的位去讀寫JSON。它不僅提供了jackson-databind,而且提供了和Java8一起運作的時候相當有用的組件:jackson-datatype-jdk8, jackson-datatype-jsr310 和jackson-module-parameter-names。如果你曾經手動地依賴這些組件,現在可以依賴這個新的starter取代。

HTTP/2 支持

為 Tomcat,Undertow 和 Jetty 提供 HTTP / 2 支持。支持取決於所選的 Web 伺服器和應用程式環境(因為 JDK 8 不支持該協議)。

配置屬性的綁定

在 Spring Boot 2.0 中,用於綁定Environment屬性的機制@ConfigurationProperties已經完全徹底修改。我們藉此機會收緊了鬆散綁定的規則,並修複了 Spring Boot 1.x 中的許多不一致之處。

新的BinderAPI 也可以@ConfigurationProperties直接在你自己的代碼之外使用。例如,下麵將結合到List的CustomerProperty對象:

List<CustomerProperty> people = Binder.get(applicationContext.getEnvironment())
    .bind("customer.property", Bindable.listOf(CustomerProperty.class))
    .orElseThrow(IllegalStateException::new);

配置源可以像這樣在 YAML 中表示:

customer:
  property:
  - first-name: wang
    last-name: lao
  - first-name: li
    last-name: sheng

Actuator 改進

在 Spring Boot 2.0 中 Actuator endpoints 有很大的改進。所有 HTTP Actuator endpoints 現在都在該/actuator路徑下公開,並且生成的 JSON 有效負載得到了改進。

我們現在也不會在預設情況下暴露很多端點。如果您要升級現有的 Spring Boot 1.5 應用程式,請務必查看遷移指南並特別註意該management.endpoints.web.exposure.include屬性。

HikariCP

Spring Boot 2.0 中的預設資料庫池技術已從 Tomcat Pool 切換到 HikariCP。我們發現 Hakari 提供了卓越的性能,我們的許多用戶更喜歡 Tomcat Pool

初始化

資料庫初始化邏輯在 Spring Boot 2.0 中已經合理化。Spring Batch,Spring Integration,Spring Session 和 Quartz的初始化現在僅在使用嵌入式資料庫時才會預設發生。該enabled屬性已被替換為更具表現力枚舉。例如,如果你想一直執行 Spring Batch 的初始化,您可以設置spring.batch.initialize-schema=always。

如果 Flyway 或 Liquibase 正在管理您的 DataSource 的模式,並且您正在使用嵌入式資料庫,Spring Boot 現在會自動關閉 Hibernate 的自動 DDL 功能。

配置文件綁定

1.簡單類型
在Spring Boot 2.0中對配置屬性載入的時候會除了像1.x版本時候那樣移除特殊字元外,還會將配置均以全小寫的方式進行匹配和載入。所以,下麵的4種配置方式都是等價的:

  • properties格式:
spring.jpa.databaseplatform=mysql
spring.jpa.database-platform=mysql
spring.jpa.databasePlatform=mysql
spring.JPA.database_platform=mysql
  • yaml格式:
spring:
  jpa:
    databaseplatform: mysql
    database-platform: mysql
    databasePlatform: mysql
    database_platform: mysql

Tips:推薦使用全小寫配合-分隔符的方式來配置,比如:spring.jpa.database-platform=mysql

2.List類型
在properties文件中使用[]來定位列表類型,比如:

spring.my-example.url[0]=http://example.com
spring.my-example.url[1]=http://spring.io

也支持使用逗號分割的配置方式,上面與下麵的配置是等價的:

spring.my-example.url=http://example.com,http://spring.io

而在yaml文件中使用可以使用如下配置:

spring:
  my-example:
    url:
      - http://example.com
      - http://spring.io

也支持逗號分割的方式:

spring:
  my-example:
    url: http://example.com, http://spring.io

註意:在Spring Boot 2.0中對於List類型的配置必須是連續的,不然會拋出UnboundConfigurationPropertiesException異常,所以如下配置是不允許的:
name[0]=aaa
name[2]=bbb
在Spring Boot 1.x中上述配置是可以的,name[1]由於沒有配置,它的值會是null

3.Map類型
Map類型在properties和yaml中的標準配置方式如下:

properties格式:

spring.my-example.foo=bar
spring.my-example.hello=world

yaml格式:

spring:
  my-example:
    foo: bar
    hello: world

註意:如果Map類型的key包含非字母數字和-的字元,需要用[]括起來,比如:

spring:
  my-example:
    '[foo.baz]': bar

測試
對 Spring Boot 2.0 中提供的測試支持進行了一些補充和調整:

@WebFluxTest已添加新註釋以支持 WebFlux 應用程式的“切片”測試。
Converter和GenericConverter豆類現在自動掃描@WebMvcTest和@WebFluxTest。
@AutoConfigureWebTestClient已經添加了一個註釋來提供一個WebTestClientbean 供測試使用。註釋會自動應用於@WebFluxTest測試。
增加了一個新的ApplicationContextRunner測試實用程式,可以很容易地測試您的自動配置。我們已將大部分內部測試套件移至此新模型。詳細信息請參閱更新的文檔。

升級遇到的一些問題總結

1.Spring Data JPA 2.0.x findOne() 無效

在使用 Spring Data JPA 中,根據 主鍵獲得對象,一般是使用<S extends T> S findOne(Example<S> example); 方法,或者 T getOne(ID id);,在 spring-data-jpa 2.0.x版本中,獲取單個對象的方法改為 Optional<T> findById(ID id);返回的是一個Optional<T>(java8新特性)Optional 類是一個可以為null的容器對象。如果值存在則isPresent()方法會返回true,調用get()方法會返回該對象。delete()方法和findOne()類似也被去掉了,可以使用deleteById(Long id)來替換,還有一個不同點是deleteById(Long id)預設實現返回值為void。

spring-data-jpa 1.5.2 的CrudRepository 介面

@NoRepositoryBean
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> {

    <S extends T> S save(S entity);

    <S extends T> Iterable<S> save(Iterable<S> entities);

    T findOne(ID id);

    boolean exists(ID id);

    Iterable<T> findAll();

    Iterable<T> findAll(Iterable<ID> ids);

    long count();

    void delete(ID id);

    void delete(T entity);

    void delete(Iterable<? extends T> entities);

    void deleteAll();
}

spring-data-jpa 2.0.8 的CrudRepository 介面

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {

    <S extends T> S save(S entity);

    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    Optional<T> findById(ID id);

    boolean existsById(ID id);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> ids);

    long count();

    void deleteById(ID id);

    void delete(T entity);

    void deleteAll(Iterable<? extends T> entities);

    void deleteAll();
}

2.@GeneratedValue(strategy = GenerationType.AUTO)Spring Boot 2.0 需要指定主鍵的自增策略,這個和 Spring Boot 1.0 有所區別,1.0 會使用預設的策略@GeneratedValue(strategy = GenerationType.IDENTITY)

@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;

3.jpa2.0的方言設置如果需要指定InnoDB存儲引擎可以使用database-platform: org.hibernate.dialect.MySQL57InnoDBDialect預設會使用myisam(不支持事務)在jpa中無法體現換成mybatis可以很好的驗證。

4.日誌類報錯:Spring Boot 2.0 預設不包含 log4j,建議使用 slf4j 。

import org.apache.log4j.Logger;
protected Logger logger = Logger.getLogger(this.getClass());

改為:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
protected Logger logger =  LoggerFactory.getLogger(this.getClass());

5.Thymeleaf 3.0 預設不包含佈局模塊。

將 Pom 包升級到 2.0之後,訪問首頁的時候一片空白什麼都沒有,查看後臺也沒有任何的報錯信息,首先嘗試著跟蹤了 http 請求,對比了一下也沒有發現什麼異常,在查詢 Thymeleaf 3.0 變化時才發現:Spring Boot 2.0 中spring-boot-starter-thymeleaf 包預設並不包含佈局模塊,需要使用的時候單獨添加,添加佈局模塊如下:

<dependency>
   <groupId>nz.net.ultraq.thymeleaf</groupId>
   <artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

6.分頁組件PageRequest變化。

在 Spring Boot 2.0 中 ,方法new PageRequest(page, size, sort) 已經過期不再推薦使用,推薦使用以下方式來構建分頁信息:
Pageable pageable =PageRequest.of(page, size, Sort.by(Sort.Direction.ASC,"id"));
跟蹤了一下源碼發現PageRequest.of()方法,內部還是使用的new PageRequest(page, size, sort),只是最新的寫法更簡潔一些。

public static PageRequest of(int page, int size, Sort sort) {
    return new PageRequest(page, size, sort);
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 通過這張圖我們很明顯就可以看出了區別: 普通函數調用的時候this的指向是window 而構造函數調用的時候this的指向是這個對象 列印結果是:凡塵 18 為什麼會是一個false呢???如果你聽過凡塵老師講課的話,在ES6的一張說過一道面試題。 創建構造函數的時候js執行了那些操作? 1、在記憶體 ...
  • 一、Express框架 1.1基本使用 創建http伺服器特別麻煩,express框架解決了這個的問題。 Express在node界的地位,就相當於jQuery在DOM界的地位。jQuery的核心就是“批量”,1個jQuery對象中可以封裝多個原生對象。Express的核心就是中間件,Express ...
  • 介紹 Vue.js + Nuxt.js 項目中如何使用、自定義錯誤信息、自定義規則 Vee-validate 校驗表單 ...
  • 在寫單文件組件時,一般都是把標簽、腳本、樣式寫到一起,這樣寫個人感覺有點不夠簡潔,所以就想著把樣式分離出去。 採用import載入樣式 在局部作用域(scoped)採用@import載入進來的樣式文件,想法是美好的。以為這樣載入進來的樣式文件也只對當前組件有效;可現實是殘酷的,這樣載入進來的樣式無法 ...
  • 一、路由機制(靜態資源文件處理) 1.1 Nodejs沒有根目錄 MIME類型:http://www.w3school.com.cn/media/media_mimeref.asp 在Apache中,它會自動將htdocs文件夾提供靜態化路由服務。 但是Nodejs沒有這個機制。 在文件夾中創建這樣 ...
  • 在單頁面應用程式(SPA)中,有些頁面的佈局結構是上下兩塊是固定,中間內容是變化的。這時在入口處固定上下部分就可以很好的解決這一問題。有少部分頁面沒有上下部分或不需要(如:用戶註冊、登陸頁面),針對這一情況怎麼解決 相容這兩種情況解決方案: App.vue 在入口處單個路由輸出 Frame.vue ...
  • 好處:方便了後端對HTTP請求中參數進行核驗,只需一次編寫效驗器,一行代碼便可對所有參數的pojo進行參數核驗!而且更改效驗邏輯時只需要更改效驗器類即可,實現瞭解耦合。 只需要程式員按照規範開發一個ParameterValidator類(如下圖1),將所有效驗方法寫在該類中即可在任意地方使用一行代碼 ...
  • 原型模式概述 定義:使用原型實例指定待創建對象的類型,並且通過複製這個原型來創建新的對象。簡單的來說就是克隆(Clone),通過已經存在的,將其複製而產生新的。原型模式屬於創建型模式,將一個原型對象傳給要發動創建的對象(客戶端對象),該對象通過請求原型對象複製自己來實現創建過程。 既然是通過Clon ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...