Spring Boot 3.4 发布

从 Spring Boot 3.3 升级

RestClient 和 RestTemplate

已添加对自动配置 RestClientRestTemplate 以使用 Reactor NettyHttpClientJDKHttpClient 的支持。按优先顺序,现在支持的客户端如下:

  • Apache HTTP Components(HttpComponentsClientHttpRequestFactory
  • Jetty Client (JettyClientHttpRequestFactory
  • Reactor Netty HttpClientReactorClientHttpRequestFactory
  • JDK HttpClientJdkClientHttpRequestFactory
  • Simple JDK HttpURLConnectionSimpleClientHttpRequestFactory

需要注意的是,如果类路径上没有 HTTP Client 库,就可能会使用 JdkClientHttpRequestFactory,而之前使用的是 SimpleClientHttpRequestFactory。可以通过设置 spring.http.client.factory 来选择特定的客户端。支持的值包括 http-componentsjettyreactorjdksimple

默认情况下,所有五个客户端都会自动跟随重定向。要禁用此行为,可将 spring.http.client.redirects 设置为 dont-follow

Apache HTTP Components 和 Envoy

Apache HTTP Components(组件)更改了 HttpClient 中有关 HTTP/1.1 TLS 升级的默认设置。大多数代理服务器都能顺利处理升级,但 EnvoyIstio 可能会遇到问题。

如果需要恢复以前的行为,可以使用新的 ClientHttpRequestFactoryBuilder 定义一个 HttpComponentsClientHttpRequestFactoryBuilder 并应用以下自定义设置:

@Bean
public HttpComponentsClientHttpRequestFactoryBuilder httpComponentsClientHttpRequestFactoryBuilder() {
    return ClientHttpRequestFactoryBuilder.httpComponents()
            .withDefaultRequestConfigManagerCustomizer((builder) -> builder.setProtocolUpgradeEnabled(false));
}

配置 Bean 的属性验证

在之前的版本中,当使用 @Validated 注解的 @ConfigurationProperties 类通过诸如 Hibernate Validator 这样的 Bean Validation 实现进行验证时,会在绑定时对嵌套属性进行验证,而不管是否使用了 @Valid。在 Spring Boot 3.4 版本中,现在验证遵循 Bean Validation 规范的行为。验证是从 @ConfigurationProperties 注解的类开始进行的,只有在相应字段使用 @Valid 注解时,验证才会级联到嵌套属性。

升级时,检查带有 Bean 验证约束的 @ConfigurationProperties 类。在需要验证层级联嵌套属性的地方添加 @Valid

基于 Bean 的条件

@ConditionalOnBean@ConditionalOnMissingBean@Bean 方法上使用时的行为发生了变化,当设置了注解属性时。与以前一样,这两个条件都将使用 @Bean 方法的返回类型作为要匹配的类型的默认值。在以前,如果设置了 nametypevalue,则不会使用此默认值。从 Spring Boot 3.4 开始,如果设置了 annotation(注解),也不会使用此默认值。要恢复先前的行为,请同时指定一个 value(值),该值是 @Bean 方法的返回类型,以及 annotation(注解)。

优雅停机

嵌入式 Web 服务器(Jetty、Rector Netty、Tomcat 或 Undertow)的优雅关机现在已默认启用。如果需要恢复以前的行为,可将 server.shutdown 设置为 immediate

用于构建 OCI 镜像的 Paketo Tiny Builder

使用 Maven spring-boot:build-image Goal 或 Gradle bootBuildImage Task 为 JVM 应用构建 OCI 镜像时使用的默认 Cloud Native Buildpacks Builder 已从 paketobuildpacks/builder-jammy-base 更改为 paketobuildpacks/builder-jammy-java-tiny。这将使镜像更小。tiny Builder 不包含 shell,因此可能不适用于需要启动脚本来运行程序的应用。有关自定义 Builder 的信息,请参阅 MavenGradle 文档。

Testcontainer 和动态属性

通过注入 DynamicPropertyRegistry 来定义动态属性的支持已被弃用,现在尝试这样做将默认失败。与其注入 DynamicPropertyRegistry,不如实现一个单独的 @Bean 方法来返回 DynamicPropertyRegistrar。这个单独的 Bean 方法应注入将从中获取属性值的容器。这样可以解决一些容器生命周期问题,并确保在使用属性之前,已经启动了获取属性值的容器。

如果希望继续注入 DynamicPropertyRegistry(可能会遇到上述生命周期问题),可将 spring.testcontainers.dynamic-property-registry-injection 设置为 warnallow。前者将记录警告日志,同时允许使用注入的 DynamicPropertyRegistry。后者将默许使用注入的 DynamicPropertyRegistry,完全恢复 Spring Boot 3.3 的行为。

@AutoConfigureTestDatabase 和容器

@AutoConfigureTestDatabase 注解现在会尝试检测数据库是否来自容器。如果要将注解用于容器数据库,则无需再添加 replace=Replace.NONE

如果需要恢复到旧的行为,可在注解中设置 replace=Replace.AUTO_CONFIGURED

控制对 Actuator 端点的访问

对启用和禁用端点的支持进行了重新设计,用更精细的访问模型取代了原来提供的 on/off(开/关)支持。除了禁用端点(none 权限)和完全启用端点(unrestricted 权限)外,新模型还支持只允许 read-only(只读)访问端点操作。

以下属性已被弃用:

  • management.endpoints.enabled-by-default
  • management.endpoint.<id>.enabled

替代属性为:

  • management.endpoints.access.default
  • management.endpoint.<id>.access

同样,@Endpoint 上的 enableByDefault 属性已被弃用,取而代之的是一个新的 defaultAccess 属性。

作为这些更改的一部分,无论使用 @ConditionalOnEnabledEndpoint 与否,默认启用现在都是一致应用的。如果在升级时失去了对端点的访问权限,可将 management.endpoint.<id>.access 设置为 read-onlyunrestricted,或将 management.endpoint.<id>.enabled 设置为 true,以使端点再次可访问。

此外,还引入了一个新属性,允许运维控制允许访问 Actuator 端点的级别:

  • management.endpoints.access.max-permitted

此属性限制了可能已为端点配置的任何访问权限。例如,如果 management.endpoints.access.max-permitted 设置为 read-only,而 management.endpoint.loggers.access 设置为 unrestricted,则只允许对 loggers 端点进行只读访问。

暴露 Cloud Foundry ConditionalOnAvailableEndpoint

@ConditionalOnAvailableEndpoint 一起使用的 EndpointExposure.CLOUD_FOUNDRY 枚举值已被弃用,转而使用 EndpointExposure.WEB。典型的 Spring Boot 应用可能不会受到此更改的影响,但是,如果你有自定义的 Cloud Foundry 特定 Actuator 端点 bean,则应更新你的条件以使用 EndpointExposure.WEB

HtmlUnit 4.3

HtmlUnit 已升级至 4.3。升级后,依赖坐标从 net.sourceforge.htmlunit:htmlunit 变为 org.htmlunit:htmlunitpackage 名称从 com.gargoylesoftware.htmlunit. 变为 org.htmlunit。升级时,请相应更新构建配置和 import

Selenium HtmlUnit 4.22

Selenium HtmlUnit 已更新至 4.22。升级后,依赖坐标从 org.seleniumhq.selenium:htmlunit-driver 变为 org.seleniumhq.selenium:htmlunit3-driver。升级时,请相应更新你的构建配置。

WebJars Locator 整合

为了获得更快的启动时间和更高效的 WebJars 资源解析(参考这里),你需要更新 pom.xml/build.gradle 以依赖 org.webjars:webjars-locator-lite 而不是 org.webjars:webjars-locator-core(这两个依赖项都由 Spring Boot 管理)。注意,Spring 中的 org.webjars:webjars-locator-core 支持现已过时,并将在未来版本中移除。请参阅有关此功能的 参考文档 部分。

删除了 OkHttp 的依赖管理

Spring Boot 不再依赖 OkHttp,因此不再管理其版本。如果你的应用依赖于 OkHttp,请更新构建,以使用符合需求的 OkHttp 版本。

Spring Boot 3.2 中的弃用

Spring Boot 3.2 中被弃用并标记为将在 3.4 中移除的类、方法和属性已在此版本中移除。请在升级前确保没有调用已废弃的方法。

最低要求的变更

Gradle

不再支持 Gradle 7.5、8.0、8.1、8.2 和 8.3。现在需要 Gradle 7.x(7.6.4 或更高版本)或 Gradle 8.x(8.4 或更高版本)。

最新的和值得关注的地方

你可以查看 配置更改日志,了解配置更改的完整概览。

结构化日志记录

通过对 Elastic Common Schemaecs)、Graylog Extended Log Formatgelf) 和 Logstashlogstash)的内置支持,引入了对结构化日志的支持。 要启用结构化文件日志记录,可将 logging.structured.format.file 设置为 ecselflogstash。同样,要启用结构化控制台日志,可将 logging.structured.format.console 设置为相应的值。

要进一步了解 Spring Boot 对结构化日志的支持,包括如何定义自定义格式,请参阅 参考文档

@Fallback Bean

@ConditionalOnSingleCandidate 现在支持 @Fallback Bean。如果有单个 Primary Bean,条件就会匹配;如果没有 Primary Bean,如果有单个非 Fallback Bean,条件也会匹配。

定义额外 Bean

在类型匹配时,基于 Bean 的条件现在会忽略任何非默认候选 Bean。通过声明 Bean 不是默认候选(使用 @Bean(defaultCandidate=false)),现在可以定义自动配置类型的 Bean,而不会导致相同类型的自动配置 Bean Back Off。这减少了在同一应用中使用 两个 DataSource Bean两个 EntityManagerFactory Bean 时所需的配置。

ClientHttpRequestFactory Builder

新增的 ClientHttpRequestFactoryBuilder 接口可让你为特定技术构建 ClientHttpRequestFactory 实例。 Builder 允许对底层组件进行细粒度定制,并以一致的方式应用通用设置。

使用接口的静态工厂方法,可为特定库创建以下 Builder:

  • Apache HTTP Components (ClientHttpRequestFactoryBuilder.httpComponents()
  • Jetty Client (ClientHttpRequestFactoryBuilder.jetty()
  • Reactor Netty HttpClientClientHttpRequestFactoryBuilder.reactor()
  • JDK HttpClientClientHttpRequestFactoryBuilder.jdk()
  • Simple JDK HttpURLConnectionClientHttpRequestFactoryBuilder.simple()

更多详情,包括如何使用配置属性应用常用设置,请参阅更新的 参考文档

可观测性的改进

应用分组

新的 spring.application.group 属性可用于将应用分组,例如,如果它们都属于某个业务单元或一个更大的应用调度。设置该属性后,日志信息中也会包含该属性。可以使用 logging.include-application.group 属性控制这一行为。Application Group 也会自动添加到 OpenTelemetry Resource 中。

OTLP

现在可以通过 gRPC 传输发送 OTLP Span。为此,请将新的配置属性 management.otlp.tracing.transport 设置为 grpc。该属性默认为 http。服务连接支持也已添加。

management.otlp.logs 下的新属性可用于自动配置 OpenTelemetryOtlpHttpLogRecordExporterSdkLoggerProvider

可观测性的其他更新

ProcessInfoContributor 现在还能显示有关堆和非堆使用情况的内存信息。

新的 management.otlp.tracing.export.enabledmanagement.wavefront.tracing.export.enabledmanagement.zipkin.tracing.export.enabled 属性现在可用于更精细地启用或禁用 Trace 导出。

AssertJ 支持 MockMvc

当 AssertJ 位于 classpath 上时,MockMvcTester 会自动配置。MockMvcTester 可让你使用 Fluent 风格的 API 来定义请求和断言。它可以在任何 MockMvc 可以使用的地方进行注入。

有关详细信息,请参阅 Spring Framework 参考文档中的 专门章节

Spring Pulsar

现在提供了配置属性用于配置默认的租户和命名空间。当使用未完全限定的 Topic URL 来消费或生产消息时,默认值将应用。你可以使用 spring.pulsar.defaults.topic.tenantspring.pulsar.defaults.topic.namespace 配置属性进行配置,或者定义自己的 PulsarTopicBuilder Bean。设置 spring.pulsar.defaults.topic.enabled=false 可禁用默认值。

新增了 PulsarContainerFactoryCustomizer 接口,以支持对自动配置的 PulsarContainerFactory 进行自定义。

spring.pulsar.consumer.subscription.name 配置属性现在适用于自动配置的 Pulsar 监听器容器。

引入了两个新的配置属性,用于配置 Pulsar 客户端的并发性:

  • spring.pulsar.client.threads.io 控制用于处理 Broker 连接的线程数量。
  • spring.pulsar.client.threads.listener 控制用于消息监听的线程数。

最后,新的 spring.pulsar.listener.concurrency 属性可用于控制自动配置的 Pulsar 消息监听器容器的并发性。

Couchbase 认证

客户端证书(Client Certificate)现在可用于验证 Couchbase 群集,以替代基本的用户名和密码验证。更多详情,请参阅 参考文档

FreeMarker

自动配置 FreeMarker 的配置对象所使用的 FreeMarker 变量现在可以自定义。为此,请定义一个或多个 FreeMarkerVariablesCustomizer 类型的 Bean。这些 Bean 将根据其定义的顺序(如果有)被调用。

通过 ActiveMQ Classic 支持嵌入式 Broker

现在 ActiveMQ Classic 再次支持嵌入式代理,自动配置已更新以支持该功能。

注意,与 Spring Boot 2.7.x 不同,ActiveMQ Starter 仅支持客户端。要使用嵌入式 Broker,应在应用中添加 org.apache.activemq:activemq-broker

配置元数据

注解处理器(Annotation Processor)现在可以检测到 Enum 的默认值。如果你手动添加了元数据以提供自定义属性的值,请务必将其删除。

废弃和替换自动配置类

为了使自动配置的演进更加容易,我们引入了对自动配置类的废弃和替换的支持。可在新的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.replacements 文件中声明替换。要了解更多信息,请参阅 参考文档

虚拟线程

如果启用了虚拟线程,以下组件将使用虚拟线程:

  • OtlpMeterRegistry
  • Undertow Web 服务器

镜像构建的改进

Spring Boot 现在默认使用 paketobuildpacks/builder-jammy-java-tiny。该 Builder 开箱即支持 ARM 和 x64 平台。

Maven 和 Gradle 构建 OCI 镜像的插件中新增了一个 trustBuilder 选项。此选项控制 CNB 生命周期的调用方式,在使用来自不受信任来源的 Builder 时提供了改进的安全性。默认情况下,来自 Paketo 项目、HerokuGoogle 的构建器是可信任的。有关详细信息,请参阅 MavenGradle 文档。

Maven 和 Gradle 构建 OCI 镜像的插件中新增了一个 imagePlatform 选项。此选项可用于指定任何 CNB Builder、运行时和 Buildpack 镜像的操作系统和架构,以便运行 CNB Builder。当主机平台支持模拟其他操作系统/架构(例如,在使用 Apple 芯片的 Mac 上使用 Rosetta 模拟 ARM 主机上的 AMD 架构)时,可以使用此选项为与主机平台的操作系统和架构不同的操作系统和架构构建镜像。有关更多信息,请参阅 MavenGradle 文档。

Docker Compose 的改进

Docker Compose 现在支持多个 Docker Compose 配置文件。

命令行参数

新属性 spring.docker.compose.start.argumentsspring.docker.compose.stop.arguments 可用于指定启动和停止服务时传递给 Docker Compose 子命令的附加命令行参数。新增的 spring.docker.compose.arguments 属性可将参数传递给 Docker Compose。

支持的更新

  • 现在 支持 Postgres POSTGRES_HOST_AUTH_METHOD=trust 环境变量。
  • 新增了对 Redis StackRedis Stack Server 的支持,分别使用 redis/redis-stackredis/redis-stack-server 容器镜像。
  • 通过 grafana/otel-lgtm 容器镜像新增了对 Grafana LGTM 的支持。
  • 新增了对 Hazelcast 的支持(使用 HazelcastConnectionDetails)。
  • 新增了对 OTLP 日志的支持。

Testcontainers 改进

  • 添加了对 org.testcontainers.kafka.KafkaContainer 的支持。
  • 使用 redis/redis-stackredis/redis-stack-server 容器镜像,添加了对 Redis StackRedis Stack Server 的支持。
  • 添加了对 org.testcontainers.grafana.LgtmStackContainer 的支持。
  • 添加了对 Hazelcast 的支持(使用 HazelcastConnectionDetails)。
  • 新增了对 OTLP 日志的支持。
  • 添加了对 RedisContainer 的支持。

Actuator

可插拔的 Actuator Exposer

现在可以通过可插拔的方式扩展 Spring Boot 以暴露 Actuator 端点。新的 EndpointExposureOutcomeContributor 接口可用于影响 @ConditionalOnAvailableEndpoint 条件。

与现有的 Cloud Foundry 支持类似,该扩展将使我们更容易提供额外的平台集成。

SSL 信息和健康检查

如果你使用 SSL Bundle,/actuator/info 下现在有一个新的端点可以显示 SSL 信息(有效日期、签发者、主题等)。该端点还会显示即将过期的证书,以提醒你需要尽快更换。新的配置属性名为 management.health.ssl.certificate-validity-warning-threshold,用于配置阈值。

还新增了 SSL 证书监控健康检查。如果证书无效,会将状态设置为 OUT_OF_SERVICE

/actuator/scheduledtasks 端点中的其他信息

/scheduledtasks Actuator 端点 现在可公开有关定时调度任务的其他元数据,如 “下一次计划执行时间” 和 “上一次执行时间、状态和异常”。

依赖升级

Spring Boot 3.4 迁移到多个 Spring 项目的新版本:

此外,还更新了许多第三方依赖,其中比较值得注意的有以下几项:

其他

除上述更改外,还有许多细微的调整和改进,包括:

  • 现在可以使用 Customizer<Liquibase> Bean 在使用 Liquibase 之前对其进行自定义了。
  • 现在可以通过定义 JCachePropertiesCustomizer Bean 来自定义用于创建 JCache CacheManager 的属性。
  • 现在可以通过定义一个名为 viewNameTranslator 的 Bean 来定制 Spring MVC 使用的 RequestToViewNameTranslator
  • 现在可以使用 LettuceClientOptionsBuilderCustomizer Bean 来定制 Lettuce 的 ClientOptions。要对整个 LettuceClientConfiguration 进行更广泛的配置,请继续使用 LettuceClientConfigurationBuilderCustomizer
  • 新的 Customizer ProxyConnectionFactoryCustomizer 可用于定制 R2DBC ProxyConnectionFactory
  • 如果发生 Spring Security 注销(Logout),现在会发布审计事件。
  • 现在可使用新属性 spring.mail.ssl.* 配置 JavaMailSender 上的 TLS 与 SSL Bundle。
  • GSON 的严格程度可使用新的 spring.gson.strictness 属性进行配置。
  • 现在可以在 JavaBean 风格配置属性的字段上使用 @Name 来自定义其名称。
  • 从其他 DataSource 派生时,如果源数据源的 URL 没有公开驱动类名,DataSourceBuilder 现在可以使用源数据源的 URL 确定驱动类名。
  • 现在,Cloud Foundry 平台可自动启用 有效性和就绪性健康探针(Liveness and Readiness health probes)
  • 新属性 spring.application.version 可用于读取和设置应用版本。该属性的默认值取自 manifestImplementation-Version
  • 自动配置的 EntityManagerFactoryBuilder 也定义了原生(如 Hibernate)属性。
  • 即使未使用 @EnableScheduling,Spring Integration 的 TaskScheduler 现在也能感知虚拟线程。
  • @ConditionalOnAvailableEndpoint 现在为端点提供了一个 value 别名。
  • 新增了用于配置 Spring Data Web 序列化模式的配置属性 spring.data.web.pageable.serialization-mode
  • 使用 SpringApplication.from(...) 语法时,现在可以指定要激活的额外 Profile。
  • Spring Boot 插件不再在 buildpack 环境中设置 BP_NATIVE_IMAGE: true
  • 已注册的 @ConfigurationProperties bean 现在尊重 @DependsOn@Description@Fallback@Lazy@Primary@Scope@Role 注解。
  • 结构化日志现在支持 Log4j2 的 MultiFormatStringBuilderFormattable
  • 新增了一个配置属性 spring.jms.listener.max-messages-per-task,用于配置监听器在一个任务中处理的消息的最大数量。
  • 默认安全配置现在公开与其他路径映射的健康组(Health Group)。此外,两个 EndpointRequest 类现在都提供 toAdditionalPaths(...) 方法。
  • Session cookie 的 partitioned 属性现在可以通过属性进行设置。
  • 新增了 server.jetty.max-form-keys 属性,用于自定义 Jetty 的最大表单 Key 值。
  • 新增了 management.otlp.logging.connect-timeoutmanagement.otlp.tracing.connect-timeout 属性,用于配置与 OTLP Collector 的连接超时。
  • 通过 OTLP 传输日志时,新增了对 gRPC 传输的支持。
  • 现在在容器中绑定用于构建过程中的 buildpacks 使用的目录时会显示警告。
  • 在使用 --enable-sbom=sbom 构建原生镜像时,现在会自动检测 SBOM
  • DatabaseDriver 枚举现在支持 ClickHouse JDBC 驱动。
  • 新属性 management.logging.export.enabledmanagement.otlp.logging.export.enabled 可用于禁用日志导出。
  • Spring Batch 使用的 TaskExecutor 可通过定义注解为 @BatchTaskExectuorTaskExecutor Bean 进行自定义。
  • Spring Session 自动配置现在支持响应式 Web 应用中的 indexed Repository 类型。
  • 如果未配置池暂停(Pool Suspension)并创建了检查点(Checkpoint),HikariCheckpointRestoreLifecycle 将记录一个警告。

Spring Boot 3.4 中的弃用

  • spring.gson.lenient 替换为 spring.gson.strictness
  • @MockBean@SpyBean 分别取代 Spring Framework 的 @MockitoBeanMockitoSpyBean
  • org.springframework.boot.ResourceBanner#getApplicationVersion(Class<?>) 改用 spring.application.version 属性。
  • org.springframework.boot.SpringApplication#logStartupInfo(boolean) 替换为 org.springframework.boot.SpringApplication#logStartupInfo(ConfigurationApplicationContext)
  • org.springframework.boot.logging.logback.ApplicationNameConverter 替换为 org.springframework.boot.logging.logback.EnclosedInSquareBracketsConverter
  • org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure#CLOUD_FOUNDRY 替换为 org.springframework.boot.actuate.autoconfigure.endpoint.expose.EndpointExposure#WEB
  • org.springframework.boot.actuate.autoconfigure.tracing.otlp.OtlpTracingConnectionDetails#getUrl() 替换为 getUrl(Transport)
  • org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryAutoConfiguration 替换为 org.springframework.boot.actuate.autoconfigure.tracing.OpenTelemetryTracingAutoConfiguration
  • OtlpAutoConfiguration 已取代 OtlpTracingAutoConfiguration
  • management.endpoints.enabled-by-defaultmanagement.endpoint.<id>.enabled 分别取代 management.endpoints.access.defaultmanagement.endpoint.<id>.access
  • @Endpoint 上的 enableByDefault 替换为 defaultAccess

Ref:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.4-Release-Notes