Spring Boot 2.x 到 3.2 的全面升級指南

程式猿DD發表於2023-12-29

Spring Framework 是一種流行的開源企業級框架,用於建立在 Java Virtual Machine (JVM) 上執行的獨立、生產級應用程式。而Spring Boot 是一個工具,可以讓使用 Spring 框架更快、更輕鬆地開發 Web 應用程式和微服務。隨著 Spring Boot 的不斷髮展,開發人員必須跟上最新的升級和變化。

最近,Spring Boot 宣佈釋出 3.2.x 版本,該版本帶來了多項新功能、錯誤修復和增強功能,鑑於對 Spring Boot 2.7.x 版本的支援已於 2023 年 11 月 18 日結束,這是一個非常重要且強制性的關注用於將 Spring Boot 應用程式升級到最新的 3.x 版本。

因此,在本文中,我們將討論如何從 Spring Boot 2.x 遷移到 3.x,以及升級的優勢以及開發人員在此過程中可能遇到的潛在困難。

升級指南

1. 升級 JDK 17

Spring Boot 3.0 需要 Java 17 作為最低版本。

如果您當前使用的是 Java 8 或 Java 11,則需要在 Spring Boot 遷移之前升級 JDK。

2. 升級到 Spring Boot 3

檢視專案及其依賴項的狀態後,請升級到 Spring Boot 3.0 的最新維護版本。

我們將使用 Spring Boot 3.2.0 進行升級。

開啟專案的 pom.xml 並更新 Spring Boot 的版本,如下所示。

<parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>3.2.0</version>
</parent>

3. 配置屬性遷移

在 Spring Boot 3.0 中,一些配置屬性被重新命名/刪除,開發人員需要相應地更新其 application.properties/application.yml

為了幫助您實現這一點,Spring Boot 提供了一個 spring-boot-properties-migrator 模組。

我們可以透過將以下內容新增到 Maven pom.xml 來新增遷移器:

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

4. 升級到 Jakarta EE

由於 Java EE 已更改為 Jakarta EE,Spring Boot 3.x 的所有依賴項 API 也從 Java EE 升級為 Jakarta EE。

簡單來說,您需要將所有 javax 的 imports 都替換為 jakarta。具體如下:

javax.persistence.*   -> jakarta.persistence.*
javax.validation.*    -> jakarta.validation.*
javax.servlet.*       -> jakarta.servlet.*
javax.annotation.*    -> jakarta.annotation.*
javax.transaction.*   -> jakarta.transaction.*

5. 調整@ConstructorBinding註解

@ConstructorBinding@ConfigurationProperties 類的型別級別不再需要,應將其刪除。

當一個類或記錄有多個建構函式時,它仍然可以在建構函式上使用,以指示應使用哪一個建構函式進行屬性繫結。

6. Spring MVC 和 WebFlux的URL匹配更改

從 Spring Framework 6.0 開始,尾部斜槓匹配配置選項已為 deprecated,其預設值設定為 false。

這意味著以前,以下控制器將匹配GET /healthGET /health/

@RestController
public class HealthController {

  @GetMapping("/health")
  public String health() {
    return "Application is Working";
  }

}

@RestController
public class HealthController {

  @GetMapping("/health")
  public Mono<String> health() {
    return Mono.just("Application is Working");
  }

}

7. RestTemplate 中的 Apache HttpClient

Spring Framework 6.0 中已刪除對 Apache HttpClient 的支援,現在由 org.apache.httpcomponents.client5:httpclient5 取代(注意:此依賴項具有不同的 groupId)。

如果您注意到 HTTP 客戶端行為存在問題,則 RestTemplate 可能會回退到 JDK 客戶端。

org.apache.httpcomponents:httpclient 可以由其他依賴項傳遞傳遞,因此您的應用程式可能依賴此依賴項而不宣告它。

下面是遷移後的RestTemplate示例:

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(){

        final SSLConnectionSocketFactory sslConnectionSocketFactory = SSLConnectionSocketFactoryBuilder.create()
                .build();
        final PoolingHttpClientConnectionManager manager = PoolingHttpClientConnectionManagerBuilder.create()
                .setSSLSocketFactory(sslConnectionSocketFactory)
                .build();
        
        final CloseableHttpClient closeableHttpClient = HttpClients.custom().setConnectionManager(manager)
                .build();
        
        final HttpComponentsClientHttpRequestFactory componentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        componentsClientHttpRequestFactory.setHttpClient(closeableHttpClient);
        
        final RestTemplate restTemplate = new RestTemplate(componentsClientHttpRequestFactory);
        return  restTemplate;
        
    }
}

8. 升級 Spring Security

Spring Boot 3.0 已升級到 Spring Security 6.0。

因此,WebSecurityConfigurerAdapter 已被棄用。 Spring鼓勵使用者轉向基於元件的安全配置。

為了演示新的配置風格,我們使用 Spring Security lambda DSL 和方法 HttpSecurity#authorizeHttpRequests 來定義我們的授權規則。

下面是使用 WebSecurityConfigurerAdapter 的示例配置,它透過 HTTP Basic 保護所有端點:

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());
    }

}

展望未來,推薦的方法是註冊一個 SecurityFilterChain bean:

@Configuration
public class SecurityConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests((authz) -> authz
                .anyRequest().authenticated()
            )
            .httpBasic(withDefaults());
        return http.build();
    }

}

9. Spring Kafka 模板升級

KafkaTemplate 方法現在返回 CompleteableFuture 而不是 ListenableFuture,後者已被棄用。

Spring Boot 2.x 中帶有 ListenableFuture 的 Kafka 模板:

private RoutingKafkaTemplate routingKafkaTemplate;

public void send(){
    ListenableFuture<SendResult<Object,Object>> future = routingKafkaTemplate.send("Message","topic");

    future.addCallback(new ListenableFutureCallback<>() {
        @Override
        public void onFailure(Throwable ex) {
            log.error(ex);
        }

        @Override
        public void onSuccess(SendResult<Object, Object> result) {
            log.info("success");
        }
    });
}

Spring Boot 3.x 中帶有 CompletableFuture 的 Kafka 模板:

private RoutingKafkaTemplate routingKafkaTemplate;

public void send() {
    CompletableFuture<SendResult<Object, Object>> future = routingKafkaTemplate.send("Message", "topic");
    future.thenAccept(log::info)
            .exceptionally(exception -> {
                log.error(exception);
                return null;
            });
}

10. Spring Doc OpenAPI 升級

springdoc-openapi用於為Spring Boot 專案自動生成 API 檔案。

springdoc-openapi的工作原理是在執行時檢查應用程式,以根據 spring 配置、類結構和各種註釋推斷 API 語義。

對於 spring-boot 3 支援,請確保使用 springdoc-openapi v2。

WebMVC 專案的 Spring Doc OpenAPI 升級

對於 WebMVC 專案,您需要在 pom.xml. 檔案中包含以下依賴項。

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.3.0</version>
</dependency>

WebFlux 專案的 Spring Doc OpenAPI 升級

對於 WebFlux 專案,您需要在 pom.xml. 檔案中包含以下依賴項。

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webflux-ui</artifactId>
    <version>2.3.0</version>
</dependency>

今日分享就到這裡,感謝閱讀!如果您學習過程中如遇困難?可以加入我們超高質量的Spring技術交流群,參與交流與討論,更好的學習與進步!更多Spring Boot教程可以點選直達!,歡迎收藏與轉發支援!

歡迎關注我的公眾號:程式猿DD。第一時間瞭解前沿行業訊息、分享深度技術乾貨、獲取優質學習資源

相關文章