新項(xiàng)目為什么決定用 Spring Boot 3.1 + JDK 17了
大家好,我是哪吒。
一、Spring Boot 3.1正式發(fā)布
經(jīng)過(guò)半年的沉淀 Spring Boot 3.1于2023年5月18日正式發(fā)布了,帶來(lái)了許多令人興奮的新特性和改進(jìn)。
本篇博客將詳細(xì)介紹Spring Boot 3.1的新特性、升級(jí)說(shuō)明以及核心功能的改進(jìn)。
同時(shí),2.6.x 版本線(xiàn)已經(jīng)停止維護(hù)了,最新支持版本如下圖所示:
最新支持版本
下圖時(shí)間軸展示了2.7.x 這也是目前唯一正在維護(hù)的 2.x 版本線(xiàn)了,商業(yè)支持的版本也只有 2.5.x 了。
商業(yè)支持的版本
二、最低環(huán)境要求
Spring Boot 3.1.0 需要Java 17,并且兼容 Java 20(包括 Java 20)。 還需要Spring Framework 6.0.9或更高版本。
1、為以下構(gòu)建工具提供顯式構(gòu)建支持:
2、Spring Boot 支持以下嵌入式 servlet 容器:
3、GraalVM本地鏡像:
可以使用 GraalVM 22.3 或更高版本將 Spring Boot 應(yīng)用程序轉(zhuǎn)換為本機(jī)映像。
可以使用原生構(gòu)建工具Gradle/Maven 插件或native-imageGraalVM 提供的工具來(lái)創(chuàng)建圖像。您還可以使用原生圖像 Paketo buildpack創(chuàng)建原生圖像。
4、支持以下版本:
三、核心特性
1、Apache HttpClient 4 的依賴(lài)管理
Spring Framework 6 中刪除了RestTemplate對(duì)Apache HttpClient 4 的支持,取而代之的是 Apache HttpClient 5。Spring Boot 3.0 包括 HttpClient 4 和 5 的依賴(lài)管理。繼續(xù)使用 HttpClient 4 的應(yīng)用程序在使用時(shí)可能會(huì)遇到難以診斷的錯(cuò)誤。Spring Boot 3.1 移除了 HttpClient 4 的依賴(lài)管理,以鼓勵(lì)用戶(hù)轉(zhuǎn)而使用 HttpClient 5。
HttpClient 5 是Apache HttpComponents中的一個(gè) HTTP 客戶(hù)端庫(kù),可以用來(lái)發(fā)送 HTTP 請(qǐng)求和接收 HTTP 響應(yīng)。下面是 HttpClient 5 的簡(jiǎn)單使用示例:
(1)添加 HttpClient 5 的依賴(lài)
在 Maven 項(xiàng)目中,可以通過(guò)在 pom.xml 文件中添加以下依賴(lài)將 HttpClient 5 添加到項(xiàng)目中:
<dependencies>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient5</artifactId>
<version>5.1</version>
</dependency>
</dependencies>
(2)創(chuàng)建 HttpClient 實(shí)例:
HttpClient httpClient = HttpClientBuilder.create().build();
(3)創(chuàng)建 HttpGet 請(qǐng)求:
HttpGet httpGet = new HttpGet("https://www.example.com/");
(4)發(fā)送請(qǐng)求并獲取響應(yīng):
HttpResponse response = httpClient.execute(httpGet);
(5)處理響應(yīng):
int statusCode = response.getStatusLine().getStatusCode();
String responseBody = EntityUtils.toString(response.getEntity());
其中,response.getStatusLine().getStatusCode() 可以獲取響應(yīng)狀態(tài)碼,EntityUtils.toString(response.getEntity()) 可以獲取響應(yīng)正文。
(6)完整的代碼如下:
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
public class HttpClientExample {
public static void main(String[] args) throws Exception {
HttpClient httpClient = HttpClientBuilder.create().build();
HttpGet httpGet = new HttpGet("https://www.example.com/");
HttpResponse response = httpClient.execute(httpGet);
int statusCode = response.getStatusLine().getStatusCode();
String responseBody = EntityUtils.toString(response.getEntity());
System.out.println("Status code: " + statusCode);
System.out.println("Response body: " + responseBody);
}
}
2、Servlet 和過(guò)濾器注冊(cè)
ServletRegistrationBean如果注冊(cè)失敗,和類(lèi)FilterRegistrationBean現(xiàn)在將失敗,IllegalStateException而不是記錄警告。如果您需要舊的行為,您應(yīng)該調(diào)用setIgnoreRegistrationFailure(true)您的注冊(cè) bean。
3、Git 提交 ID Maven 插件版本屬性
用于覆蓋 的版本的屬性io.github.git-commit-id:git-commit-id-maven-plugin已更新以與其工件名稱(chēng)保持一致。為了適應(yīng)這種變化,請(qǐng)git-commit-id-plugin.version在git-commit-id-maven-plugin.version您的pom.xml。
4、Hibernate 6.2
Spring Boot 3.1 升級(jí)到 Hibernate 6.2。請(qǐng)參閱Hibernate 6.2 遷移指南以了解這對(duì)您的應(yīng)用程序有何影響。
Hibernate 6.2 遷移指南
5、Jackson 2.15
Spring Boot 3.1 升級(jí)到 Jackson 2.15。請(qǐng)參閱Jackson wiki以了解這對(duì)您的應(yīng)用程序有何影響。
2.15 中的一個(gè)顯著變化是引入了處理限制。要調(diào)整這些約束,請(qǐng)定義Jackson2ObjectMapperBuilderCustomizer類(lèi)似于以下內(nèi)容:
@Bean
Jackson2ObjectMapperBuilderCustomizer customStreamReadConstraints() {
return (builder) -> builder.postConfigurer((objectMapper) -> objectMapper.getFactory()
.setStreamReadConstraints(StreamReadConstraints.builder().maxNestingDepth(2000).build()));
}
6、Mockito 5
Spring Boot 3.1 升級(jí)到 Mockito 5,特別是 5.3。請(qǐng)參閱 Mockito 發(fā)行說(shuō)明以了解 Mockito 5.x 系列中的顯著變化。
7、Health Group Membership Validation
現(xiàn)在在啟動(dòng)時(shí)驗(yàn)證配置的健康組成員身份。如果包含或排除了不存在的健康指標(biāo),啟動(dòng)將失敗??梢越么蓑?yàn)證,恢復(fù)早期版本的行為,方法是設(shè)置management.endpoint.health.validate-group-membership為false。
四、增強(qiáng)功能
1、服務(wù)連接
引入了新的服務(wù)連接概念。此類(lèi)連接在應(yīng)用程序中由 bean 表示ConnectionDetails。這些 bean 提供了必要的細(xì)節(jié)來(lái)建立與刪除服務(wù)的連接,并且 Spring Boot 的自動(dòng)配置已更新為使用ConnectionDetailsbean。當(dāng)此類(lèi) beans 可用時(shí),它們將優(yōu)先于任何與連接相關(guān)的配置屬性。與連接本身無(wú)關(guān)的配置屬性,例如控制連接池大小和行為的屬性,仍將被使用。
此低級(jí)功能旨在作為其他高級(jí)功能的構(gòu)建塊,這些功能通過(guò)定義ConnectionDetailsbean 自動(dòng)配置服務(wù)連接。
在沒(méi)有在其他地方定義適當(dāng)?shù)?bean 的情況下…ConnectionDetails,Spring Boot 的自動(dòng)配置已更新為定義自己的基礎(chǔ),由相關(guān)配置屬性支持。這允許…ConnectionDetails注入而不必處理沒(méi)有這樣的 bean 可用并且需要回退到基于屬性的配置的情況。
2、在開(kāi)發(fā)時(shí)使用測(cè)試容器
引入了對(duì)在開(kāi)發(fā)時(shí)使用測(cè)試容器管理外部服務(wù)的支持。
在開(kāi)發(fā)時(shí)使用 Testcontainer 時(shí),可以使用新的 Maven goal( spring-boot:test-run) 和 Gradle task( bootTestRun) 通過(guò)測(cè)試 main 方法啟動(dòng)應(yīng)用程序。
Container可以使用新注釋導(dǎo)入將 Testcontainers 實(shí)例聲明為靜態(tài)字段的類(lèi)@ImportTestcontainers。
測(cè)試容器生命周期的管理得到改進(jìn),確保容器先初始化,最后銷(xiāo)毀。對(duì)可重復(fù)使用容器的支持也得到了改進(jìn)。
從方法貢獻(xiàn)屬性Container @Bean,DynamicPropertyRegistry現(xiàn)在可以注入。@DynamicPropertySource這與您在測(cè)試中使用的方式類(lèi)似。
有關(guān)詳細(xì)信息,請(qǐng)參閱下圖:
測(cè)試容器服務(wù)連接
使用 Testcontainers 時(shí),@DynamicPropertySource通常用于根據(jù)容器的設(shè)置配置應(yīng)用程序?qū)傩裕?/p>
@Container
static GenericContainer redis = new GenericContainer(DockerImageName.parse("redis").withTag("4.0.14"));
// …
@DynamicPropertySource
static void redisProperties(DynamicPropertyRegistry registry) {
registry.add("spring.data.redis.host", redis::getHost);
registry.add("spring.data.redis.port", redis::getFirstMappedPort);
}
現(xiàn)在可以簡(jiǎn)化為以下內(nèi)容:
@Container
@ServiceConnection
static GenericContainer redis = new GenericContainer(DockerImageName.parse("redis").withTag("4.0.14"));
此處,@ServiceConnection指示容器應(yīng)使用 Redis 連接詳細(xì)信息的來(lái)源。spring-boot-testcontainers提供注釋的模塊將從@ServiceConnection容器中提取這些細(xì)節(jié),同時(shí)仍然允許使用 Testcontainers API 來(lái)定義和配置它。
下圖查看注釋當(dāng)前支持的服務(wù)的完整列表@ServiceConnection。
3、Docker Compose
一個(gè)新模塊,spring-boot-docker-compose提供與 Docker Compose 的集成。當(dāng)您的應(yīng)用程序啟動(dòng)時(shí),Docker Compose 集成將在當(dāng)前工作目錄中查找配置文件。支持以下文件:
- compose.yaml
- compose.yml
- docker-compose.yaml
- docker-compose.yml
要使用非標(biāo)準(zhǔn)文件,請(qǐng)?jiān)O(shè)置該spring.docker.compose.file屬性。
默認(rèn)情況下,配置文件中聲明的服務(wù)將被啟動(dòng)docker compose up,這些服務(wù)的連接詳細(xì)信息 bean 將被添加到應(yīng)用程序上下文中,以便可以在沒(méi)有任何進(jìn)一步配置的情況下使用這些服務(wù)。當(dāng)應(yīng)用程序停止時(shí),服務(wù)將使用 關(guān)閉docker compose down。spring.docker.compose.lifecycle-management可以使用、spring.docker.compose.startup.command和配置屬性自定義此生命周期管理和用于啟動(dòng)和關(guān)閉服務(wù)的命令spring.docker.compose.shutdown.command。
下圖展示更多詳細(xì)信息,包括當(dāng)前支持的服務(wù)列表:
4、SSL 配置
RestTemplateJava KeyStore 和 PEM 編碼證書(shū)等 SSL 信任材料現(xiàn)在可以使用屬性進(jìn)行配置,并WebClient以更一致的方式應(yīng)用于各種類(lèi)型的連接,例如嵌入式 Web 服務(wù)器、數(shù)據(jù)服務(wù)。
使用 PEM 編碼證書(shū)配置 SSL示例:
帶有前綴的配置屬性spring.ssl.bundle.pem可用于以 PEM 編碼文本的形式配置信任材料包。每個(gè)包都有一個(gè)用戶(hù)提供的名稱(chēng),可用于引用該包。
當(dāng)用于保護(hù)嵌入式 Web 服務(wù)器時(shí),akeystore通常配置有證書(shū)和私鑰,如本例所示:
spring:
ssl:
bundle:
pem:
mybundle:
keystore:
certificate: "classpath:application.crt"
private-key: "classpath:application.key"
當(dāng)用于保護(hù)嵌入式 Web 服務(wù)器時(shí),truststore通常使用服務(wù)器證書(shū)配置 a,如本例所示:
spring:
ssl:
bundle:
pem:
mybundle:
truststore:
certificate: "classpath:server.crt"
5、Spring授權(quán)服務(wù)器的自動(dòng)配置
此版本提供了對(duì)Spring Authorization Server項(xiàng)目的支持以及一個(gè)新的spring-boot-starter-oauth2-authorization-server啟動(dòng)器。
示例:
如果您spring-security-oauth2-authorization-server的類(lèi)路徑上有,您可以利用一些自動(dòng)配置來(lái)設(shè)置基于 Servlet 的 OAuth2 授權(quán)服務(wù)器。
您可以在spring.security.oauth2.authorizationserver.client前綴下注冊(cè)多個(gè) OAuth2 客戶(hù)端,如以下示例所示:
spring:
security:
oauth2:
authorizationserver:
client:
my-client-1:
registration:
client-id: "abcd"
client-secret: "{noop}secret1"
client-authentication-methods:
- "client_secret_basic"
authorization-grant-types:
- "authorization_code"
- "refresh_token"
redirect-uris:
- "https://my-client-1.com/login/oauth2/code/abcd"
- "https://my-client-1.com/authorized"
scopes:
- "openid"
- "profile"
- "email"
- "phone"
- "address"
require-authorization-consent: true
my-client-2:
registration:
client-id: "efgh"
client-secret: "{noop}secret2"
client-authentication-methods:
- "client_secret_jwt"
authorization-grant-types:
- "client_credentials"
scopes:
- "user.read"
- "user.write"
jwk-set-uri: "https://my-client-2.com/jwks"
token-endpoint-authentication-signing-algorithm: "RS256"
Spring Boot 為 Spring Authorization Server 提供的自動(dòng)配置,就是為了快速上手而設(shè)計(jì)的。大多數(shù)應(yīng)用程序都需要定制,并希望定義幾個(gè) bean 來(lái)覆蓋自動(dòng)配置。
以下組件可以定義為 beans 以覆蓋特定于 Spring Authorization Server 的自動(dòng)配置:
- RegisteredClientRepository
- AuthorizationServerSettings
- SecurityFilterChain
- com.nimbusds.jose.jwk.source.JWKSource<com.nimbusds.jose.proc.SecurityContext>
- JwtDecoder
6、Docker鏡像構(gòu)建
(1)圖像創(chuàng)建日期和時(shí)間
Mavenspring-boot:build-image目標(biāo)和bootBuildImageGradle 任務(wù)現(xiàn)在有一個(gè)createdDate配置選項(xiàng),可用于將Created生成的圖像元數(shù)據(jù)中的字段值設(shè)置為用戶(hù)指定的日期或使用now當(dāng)前日期和時(shí)間。
(2)圖像應(yīng)用目錄
Mavenspring-boot:build-image目標(biāo)和bootBuildImageGradle 任務(wù)現(xiàn)在有一個(gè)applicationDirectory配置選項(xiàng),可用于設(shè)置構(gòu)建器映像中的位置,應(yīng)用程序內(nèi)容將上傳到該位置以供構(gòu)建包使用。這也將是應(yīng)用程序內(nèi)容在生成的圖像中的位置。
五、用于 GraphQL 的 Spring
1、異常處理
@GraphQlExceptionHandler在控制器中聲明的方法,或者@ControllerAdvice現(xiàn)在由 Spring for GraphQL 開(kāi)箱即用地支持控制器方法調(diào)用。此外,Spring Boot通過(guò)@ControllerAdvice配置DataFetcher、QueryDslDataFetcher、QueryByExampleDataFetcher、GraphQlSource。
2、分頁(yè)和排序
當(dāng) Spring Data 在類(lèi)路徑上時(shí),GraphQL 的 Spring 現(xiàn)在自動(dòng)配置為支持分頁(yè)和排序。
3、改進(jìn)的模式類(lèi)型生成
GraphQlSource現(xiàn)在自動(dòng)配置了一個(gè)ConnectionTypeDefinitionConfigurer. 它通過(guò)查找類(lèi)型定義名稱(chēng)以“Connection”結(jié)尾的字段來(lái)生成“Connection”類(lèi)型Connection Type,如果它們尚不存在,則添加所需的類(lèi)型定義。
4、支持使用 OTLP 導(dǎo)出跟蹤
當(dāng)io.opentelemetry:opentelemetry-exporter-otlp在類(lèi)路徑上時(shí),OtlpHttpSpanExporter將自動(dòng)配置??梢允褂胢anagement.otlp.tracing.*配置屬性自定義導(dǎo)出器的配置。
5、Wavefront Span 標(biāo)簽定制
如果您正在使用 Wavefront 并且想要為 RED 指標(biāo)自定義 span 標(biāo)簽,現(xiàn)在有一個(gè)名為的新屬性management.wavefront.trace-derived-custom-tag-keys允許您執(zhí)行此操作。
6、文件和控制臺(tái)的不同日志級(jí)別
如果您使用的是 Logback 或 Log4j2,現(xiàn)在可以選擇為控制臺(tái)日志和文件日志設(shè)置不同的日志級(jí)別。這可以使用配置屬性logging.threshold.console和來(lái)設(shè)置logging.threshold.file。
7、最大 HTTP 響應(yīng)標(biāo)頭大小
如果您使用的是 Tomcat 或 Jetty,您現(xiàn)在可以限制最大 HTTP 響應(yīng)標(biāo)頭大小。對(duì)于 Tomcat,您可以使用該server.tomcat.max-http-response-header-size屬性,而對(duì)于 Jetty,您可以使用server.jetty.max-http-response-header-size. 默認(rèn)情況下,響應(yīng)標(biāo)頭僅限于8kb。
六、spring Boot 3.1 中的棄用
已棄用 | 取而代之 |
spring.kafka.streams.cache-max-size-buffering | spring.kafka.streams.state-store-cache-max-size |
MongoPropertiesClientSettingsBuilderCustomizer | StandardMongoClientSettingsBuilderCustomizer |
org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesRegistrationAdapter | org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientPropertiesMapper |
org.springframework.boot.web.server.SslStoreProvider | SSL bundle |
七、依賴(lài)升級(jí)
Spring Boot 3.1.0 遷移到幾個(gè) Spring 項(xiàng)目的新版本:
Spring項(xiàng)目 | Versions |
Spring Authorization Server | 1.1.0 |
Spring Batch | 5.0.2 |
Spring Data | 2023.0.0 |
Spring Framework | 6.0.9 |
Spring GraphQL | 1.2.0 |
Spring HATEOAS | 2.1.0 |
Spring Integration | 6.1.0 |
Spring Kafka | 3.0.7 |
Spring LDAP | 3.1.0 |
Spring Security | 6.1.0 |
Spring Session | 3.1.0 |
Spring Web Services | 4.0.4 |
許多第三方依賴(lài)項(xiàng)也已更新,其中一些更值得注意的是:
第三方依賴(lài) | Versions |
Couchbase Java Client | 3.4.6 |
Elasticsearch Client | 8.7 |
Hibernate | 6.2 |
GraphQL Java | 20.1 |
Jackson | 2.15.0 |
Kafka | 3.4.0 |
Kotlin | 1.8.21 |
Liquibase | 4.20 |
Micrometer | 1.11.0 |
Micrometer Tracing | 1.1.1 |
Mockito | 5.3 |
Native Build Tools | 0.9.22 |
Neo4j Java Driver | 5.8.0 |
OpenTelemetry | 1.24.0 |
Rabbit AMQP Client | 5.17.0 |
Reactor BOM | 2022.0.7 |
Testcontainers | 1.18 |
Undertow | 2.3.6.Final |
八、其他
- Spring Kafka ContainerCustomizer bean現(xiàn)在被應(yīng)用于自動(dòng)配置的KafkaListenerContainerFactory。
- 添加了management.otlp.metrics.export.headers屬性,以支持向OTLP注冊(cè)表發(fā)送頭。
- JoranConfigurators bean現(xiàn)在可以在A(yíng)OT處理中使用。
- spring.kafka.admin添加了額外的close-timeout、operation-timeout、auto-startup和auto-create屬性。
- BatchInterceptor bean現(xiàn)在被應(yīng)用于自動(dòng)配置的ConcurrentKafkaListenerContainerFactory。
- Nomad已添加到已識(shí)別的CloudPlaform值列表中。
- 現(xiàn)在可以為spring.jmx指定registration-policy屬性。
- 添加了withSanitizedValue實(shí)用方法到SanitizableData中。
- 引入了RabbitTemplateCustomizer。這種類(lèi)型的bean將自定義自動(dòng)配置的RabbitTemplate。
- 支持CNB Platform API 0.11。
- spring-boot-starter-parent將Maven編譯器版本設(shè)置為配置的Java版本。
- 通過(guò)設(shè)置-Dspring-boot.build-info.skip,現(xiàn)在可以跳過(guò)build-info目標(biāo)。
- Micrometer的OtlpMeterRegistry支持聚合時(shí)間配置。
- Log4j2和Logback支持更多顏色。
- 添加了對(duì)R2DBC MySQL驅(qū)動(dòng)程序(io.asyncer:r2dbc-mysql)的依賴(lài)管理。
- 添加了對(duì)R2DBC MariaDB驅(qū)動(dòng)程序(org.mariadb:r2dbc-mariadb)的依賴(lài)管理。
- 使用OpenTelemetry時(shí),用于創(chuàng)建自動(dòng)配置的SdkTracerProvider的SdkTracerProviderBuilder可以通過(guò)定義SdkTracerProviderBuilderCustomizer bean進(jìn)行自定義。
- MockServerRestTemplateCustomizer現(xiàn)在通過(guò)新的setBufferContent方法支持啟用內(nèi)容緩沖
- 當(dāng)自動(dòng)配置Spring Batch時(shí),可以通過(guò)定義BatchConversionServiceCustomizer bean來(lái)自定義轉(zhuǎn)換服務(wù)。
- 用于創(chuàng)建JWK Set URI的JTW解碼器的構(gòu)建器可以通過(guò)定義JwkSetUriReactiveJwtDecoderBuilderCustomizer或JwkSetUriJwtDecoderBuilderCustomizer bean進(jìn)行自定義。
- 恢復(fù)了對(duì)io.r2dbc:r2dbc-mssql的依賴(lài)管理。
- Logback的根日志級(jí)別現(xiàn)在盡早默認(rèn)為INFO。
- 默認(rèn)情況下,Docker Compose現(xiàn)在使用stop而不是down停止。
本文轉(zhuǎn)載自微信公眾號(hào)「哪吒編程」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系哪吒編程公眾號(hào)。