likes
comments
collection
share

SpringBoot 3.2 支持虚拟线程!官方说明全文速览

作者站长头像
站长
· 阅读数 27

前言

SpringBoot 3.2 来了,这个版本增加了大量的新特性和改进。

本篇是翻译自官方说明,完整的可以参考这里:Spring-Boot-3.2-Release-Notes

速览

1、亮点概览

  • 支持虚拟线程
  • 对JVM检查点恢复的初始支持(项目CRaC)
  • SSL包重新加载
  • 大量的可观察性改进
  • 支持RestClient
  • 支持jdbc客户端
  • 支持Jetty 12
  • 支持Apache Pulsar的Spring
  • 支持Kafka和RabbitMQ的SSL绑定
  • 重制了嵌套的Jar处理
  • Docker镜像构建改进

2、从 Spring Boot 3.1 升级

1)、参数名称发现

Spring Boot 3.2 使用的Spring框架版本不再试图通过解析字节码来推断参数名。

如果在依赖注入或属性绑定方面遇到问题,应该仔细检查是否使用-parameters选项进行编译。

2)、记录的应用程序名称

现在,只要设置了spring.application.name属性,默认日志输出就会包含您的应用程序名称。

如果您喜欢前一种格式,可以设置日志记录,将-application-name设置为false。

3)、自动配置用户详细信息服务

spring-security-oauth2-clientspring-security-oauth2-resource-serverspring-security-sam12-service-provider中的一个或多个在类路径上时,自动配置的InMemoryUserDetailsManager现在会退出。

类似地,在响应式应用程序中,当spring-security-oauth2-clientspring-security-oauth2-resource-server中的一个或多个是类路径时,自动配置的MapReactiveUserDetailsService现在会退出。

如果您正在使用上述依赖项之一,但仍然需要在应用程序中使用InMemoryUserDetailsManagerMapReactiveUserDetailsService,请在应用程序中定义所需的bean。

4)、OTLP跟踪端点

management.otlp.tracking.endpoint的默认值已被删除。

现在,只有当management.otlp.tracing.endpoint有一个值时,otlphttpspanexporters bean才会自动配置。

要恢复旧的行为,设置management.otlp.tracing.endpoint=http://localhost:4318/v1/traces

5)、H2版本2.2

Spring Boot现在默认使用2.2版本的H2。要继续使用早期版本的H2中的数据库,可能需要执行数据迁移。

升级前请使用SCRIPT命令导出数据库。使用新版本的H2创建一个空数据库,然后使用RUNSCRIPT命令导入数据。

6)、Oracle UCP数据源

Oracle UCP数据源不再将validateConnectionOnBorrow默认设置为true。

如果您需要恢复旧的行为,您可以设置spring.datasource.oracleucp.Validate-connection-on-borrow应用程序属性设置为true。

7)、Jetty 12

Spring Boot现在支持Jetty 12。Jetty 12支持Servlet 6.0 API,使其与Tomcat和Undertow保持一致。

以前,如果您在Spring Boot 3中使用Jetty.x时,Servlet API必须降级到5.0。

这已经没有必要了。升级时删除Servlet API版本的所有覆盖。

8)、Kotlin 1.9.0和Gradle

Kotlin Gradle Plugin的1.9.0版本有一个bug,会导致额外的资源目录丢失

这将破坏本机镜像编译,因为AOT处理生成的资源不包括在本机镜像的类路径中。要解决这个问题,首先应用Kotlin的Gradle插件。

9)、嵌套Jar支持

支持Spring Boot的“Uber Jar”加载的底层代码已经重写,现在我们不再需要支持 Java 8 了

更新后的代码使用了更符合JDK期望的新URL格式。

以前的URL格式 jar:file:/dir/myjar.jar:BOOT-INF/lib/nested.jar!/com/example/MyClass.class 被替换为 jar:nested:/dir/myjar.jar/!BOOT-INF/lib/nested.jar!/com/example/MyClass.class

更新后的代码还使用java.lang.ref.Cleaner(它是JDK 9的一部分)进行资源管理。

官方尽可能确保新守则透明地取代以前的执行,预计大多数用户甚至不会注意到这个变化。

你可能会注意到一个变化,如果你直接引用其中一个启动器类,它们在新的默认启动器中有新的名称:

新的旧的
org.springframework.boot.loader.launch.JarLauncherorg.springframework.boot.loader.JarLauncher
org.springframework.boot.loader.launch.PropertiesLauncherorg.springframework.boot.loader.PropertiesLauncher
org.springframework.boot.loader.launch.WarLauncherorg.springframework.boot.loader.WarLauncher

但是,如果您确实发现了新实现的问题,我们提供了一个备用选项,允许您使用旧代码。

对于Gradle用户,你可以设置bootJar。例如:

bootJar {
  loaderImplementation = org.springframework.boot.loader.tools.LoaderImplementation.CLASSIC
}

对于Maven用户,您可以将spring-boot-plugin配置中的loaderImplementation标记设置为CLASSIC。例如:

<build>
  <plugins>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <executions>
        <execution>
          <goals>
            <goal>repackage</goal>
          </goals>
          <configuration>
            <loaderImplementation>CLASSIC</loaderImplementation>
          </configuration>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>    

10)、Spring Boot 3.0的弃用

在 Spring Boot 3.0 中弃用的类、方法和属性在此版本中已被删除。请确保在升级之前没有调用过时的方法。

3、新的和值得注意的

1、Spring for Apache Pulsar 支持

Spring Boot现在包含了Spring for Apache Pulsar项目的自动配置支持和启动pom。

2、日志关联id

Spring Boot现在会在你使用Micrometer tracing时自动记录相关ID。

3、RestClient支持

Spring Boot 3.2包含了对Spring Framework 6.1中引入的新的RestClient接口的支持。

这个接口提供了一个功能风格的阻塞HTTP API,其设计类似于WebClient。

现有的和新的应用程序可能会考虑使用RestClient作为RestTemplate的替代品。

4、RestTemplate HTTP客户端

当Jetty的HttpClient在类路径上时,Spring Boot的HTTP客户端自动检测现在将配置RestTemplateBuilder以使用Spring Framework 6.1中引入的新JettyClientHttpRequestFactory

ClientHttpRequestFactories中增加了对JdkClientHttpRequestFactory的支持。

JettyClientHttpRequestFactory不同,它没有被添加到自动检测中。要使用JdkClientHttpRequestFactory,你必须选择:

@Bean
RestTemplateBuilder restTemplateBuilder(RestTemplateBuilderConfigurer configurer) {
    return configurer.configure(new RestTemplateBuilder())
        .requestFactory(
                (settings) -> ClientHttpRequestFactories.get(JdkClientHttpRequestFactory.class, settings));
}

5、支持jdbc客户端

基于NamedParameterJdbcTemplate的存在,已经添加了jdbclient的自动配置。

如果后者是自动配置的,则spring.jdbc.template的属性.*被考虑在内。

6、支持虚拟线程

Spring Boot 3.2支持虚拟线程。要使用虚拟线程,需要在Java 21上运行,并将属性spring.threads.virtual.enabled设置为true。

1)、Servlet Web服务器

启用虚拟线程后,Tomcat和Jetty将使用虚拟线程进行请求处理。这意味着处理web请求的应用程序代码,例如控制器中的方法,将在虚拟线程上运行。

2)、用Spring WebFlux阻塞执行

Spring WebFlux对块执行的支持是自动配置的,当它是AsyncTaskExecutor时使用applicationTaskExecutor bean。applicationTaskExecutor在默认情况下和虚拟线程启用时都是AsyncTaskExecutor

3)、任务执行

当虚拟线程被启用时,applicationTaskExecutor bean将是一个配置为使用虚拟线程的SimpleAsyncTaskExecutor

任何使用应用任务执行器的地方,比如调用@Async方法时的@EnableAsync, Spring MVC的异步请求处理,以及Spring WebFlux的阻塞执行支持,现在都将使用虚拟线程。

和前面一样,任何TaskDecorator bean都应用于自动配置的执行器和spring.task.execution

应用Thread-name-prefix属性。其他spring.task.execution.*属性被忽略,因为它们特定于基于池的执行器。

SimpleAsyncTaskExecutorBuilder现在可以在应用上下文中使用,并且可以用来构建SimpleAsyncTaskExecutor。

SimpleAsyncTaskExecutorCustomizer bean可以用来定制构建的SimpleAsyncTaskExecutor

如果启用了虚拟线程,则构建器将自动配置为使用它们。

4)、任务调度

当虚拟线程被启用时,taskScheduler bean将是一个配置为使用虚拟线程的SimpleAsyncTaskScheduler

spring.task.scheduling.Thread-name-prefix属性和spring.task.scheduling.simple.应用属性。

其他spring.task.scheduling.属性将被忽略,因为它们特定于基于池的调度器。

SimpleAsyncTaskSchedulerBuilder现在可以在应用程序上下文中使用,并且可以用来构建SimpleAsyncTaskScheduler

SimpleAsyncTaskSchedulerCustomizer bean可以用来定制构建的SimpleAsyncTaskScheduler

如果启用了虚拟线程,则构建器将自动配置为使用它们。

5)、保持JVM存活

有个新属性叫spring.main.keep-alive

当设置为true时,JVM保持活动状态,即使所有其他线程都是虚拟(或守护进程)线程

6)、特定技术的集成

当启用虚拟线程时,将应用以下特定于技术的集成:

  • 虚拟线程执行器是为RabbitMQ监听器自动配置的

  • 虚拟线程执行器是为Kafka监听器自动配置的

  • Spring Data Redisclustercommandexexecutor将使用虚拟线程

  • Spring for Apache Pulsar将为自动配置的ConcurrentPulsarListenerContainerFactoryDefaultPulsarReaderContainerFactory使用virtualthreadtaskexecutor

7、初始支持JVM检查点恢复

Spring Boot 3.2 提供了对JVM检查点恢复(Project CRaC)的初始支持。

8、SSL包重新加载

SSL包现在可以在信任材料更改时自动重新加载。bundle必须通过将它的reload-on-update属性设置为true来选择使用这个功能。bundle的消费者也必须支持重新加载。

支持重载的消费者有:

  • Netty web服务器

  • Tomcat web服务器

关于重新加载SSL包的更多信息可以在参考文档中找到:features.ssl.reloading

9、可观测性的改进

你现在可以使用Micrometer的@Timed, @counts, @NewSpan, @ContinueSpan和@Observed注释。

如果在类路径中有AspectJ,那么它们现在是自动配置的。

@Scheduled方法现在被检测为可观察性。

增加了R2DBC的可观察性。要启用它,请包含io.r2dbc:r2dbc-proxy依赖项。

10、Docker镜像构建

1)、默认CNB生成器已升级

使用Maven和Gradle插件构建镜像时使用的默认CNB构建器已经更改。

GraalVM插件应用于构建时,新的默认构建器是paketobuildpacks:builder-jam -tiny

否则,新的默认构建器是paketobuildpacks:builder-jam -base

参考:builders-reference

以前的默认构建器包括一个基于Ubuntu 18.04的运行镜像,新的默认构建器包括一个基于Ubuntu 22.04的运行镜像。

这意味着任何使用新的默认设置构建的镜像都将基于Ubuntu 22.04

2)、Docker主机配置

spring-boot:build-image Maven目标和bootBuildImage Gradle任务现在使用Docker CLI配置文件来确定默认情况下应该使用的Docker守护进程的主机地址和其他连接细节。

请参阅Gradle和Maven插件文档了解更多信息:

3)、为缓存绑定挂载

CNB构建器和构建包使用的构建和启动缓存现在可以配置为使用绑定挂载而不是命名卷

这个特性是BitBucket CI的用户所要求的,因为BitBucket CI不允许从CI管道访问卷。

有关更多信息和示例,请参阅Maven和Gradle文档:

4)、构建工作区配置

CNB构建器和构建包使用的临时构建工作区现在可以配置为使用绑定挂载或自定义命名卷

有关更多信息和示例,请参阅Maven和Gradle文档。

5)、安全选项配置

应用于CNB构建器容器的安全选项现在可以自定义,以支持Docker环境,现在允许使用默认的Linux安全选项label=disable

有关更多信息,请参阅Maven和Gradle文档:

11、Spring for GraphQL的可调用支持

Spring for GraphQL现在被自动配置为使用applicationTaskExecutor。这为返回Callable的控制器方法提供了开箱即用的支持。

12、附加的OAuth2令牌验证器

自动配置的JwtDecoderReactiveJwtDecoder现在将使用任何OAuth2TokenValidator<Jwt> bean进行令牌验证。

它们包含在被配置为解码器的验证器的DelegatingOAuth2TokenValidator中。

13、Docker Compose对Neo4j的支持

Spring Boot的Docker Compose集成现在支持Neo4j

您必须在撰写的YAML中配置NEO4J_AUTH环境变量以禁用身份验证(值为none)或为neo4j用户设置密码(值为neo4j/your-password)。

14、WebSocketServerSpec配置

自动配置使用的WebSocketServerSpec可以使用spring.rsocket.server.spec命名空间的属性进行自定义。

15、Neo4j AuthTokenManager

如果定义了AuthTokenManager bean,它将用于Neo4j的身份验证。

这样的bean优先于spring.neo4j.authentication.*属性。

如果定义了自定义Neo4jConnectionDetails,则忽略AuthTokenManager bean,例如用于到TestcontainersDocker Compose托管数据库的服务连接。

16、RabbitMQ

1)、SSL捆绑包支持

RabbitMQ连接现在可以通过spring.rabbitmq.ssl.bundle属性配置为使用来自SSL bundle的SSL信任材料。

这提供了使用现有spring.rabbitmq.ssl属性将信任材料作为Java密钥库文件提供的另一种选择。

2)、消息正文大小有限

最新版本的RabbitMQ Java客户端默认限制入站消息主体的最大大小为64MB

要自定义此限制,请使用spring.rabbitmq.js文件。

引入了Max-inbound-message-body-size配置属性。

3)、RabbitMQ Stream的虚拟主机支持

增加了对RabbitMQ Stream的虚拟主机支持。如果没有显式设置,RabbitMQ Stream的虚拟主机将自动使用已配置的RabbitMQ虚拟主机

要为RabbitMQ Stream使用一个特定的虚拟主机,设置spring.rabbitmq.stream.virtual-host

17、Kafka

SSL捆绑包支持

Kafka连接现在可以通过spring.kafka.ssl.bundle属性配置为使用来自SSL bundle的SSL信任材料。

这为使用现有的spring.kafka.ssl属性将信任材料作为Java密钥库文件提供了另一种选择。

18、Oracle UCP数据源上的连接验证

Oracle UCP数据源上的默认连接验证已被删除。

在默认情况下启用3.2.0-RC1连接验证之前,不再是这种情况。

如果需要验证连接,请设置配置属性spring.datasource.oracleucp.Validate-connection-on-borrow设置为true

19、其他小的改进

1)、Jackson的EnumFeature和JsonNodeFeature中声明的功能现在可以分别使用配置属性spring.ackson.datatype.enumspring.ackson.datatype.jsonnode来启用和禁用。

2)、RestClientBuilderConfigurer,可用于将Spring Boot的默认值应用于RestClient。生成器,已添加。

3)、引入了一个新的@ConditionalOnThreading注释来帮助自动配置虚拟线程相关内容。

4)、添加了一个属性来配置Jetty服务器的最大连接量

5)、添加了对Kafka MessageListenerContainer changeConsumerThreadName属性的支持。

6)、将Function<MessageListenerContainer,String>bean自动配置为Kafka MessageListerContaine的threadNameSupplier。

7)、添加了对RabbitMQ容器forceStop属性的支持。

8)、基于WebClientZipkin发送器现在会遵守通过配置属性设置的超时。

9)、使用GraalVM时,现在会自动提供messages.propertiesmessages_*.properties的资源提示。

10)、自动配置的JdbcClientbean现在可以在使用@JdbcTest和@DataJpaTest的测试中使用。

11)、当自动配置MockMvc时,过滤器现在使用调度器类型和注册bean中的init参数进行注册。

12)、现在可以并行初始化测试容器,请将spring.testcontainers.beans.startup设置为并行。

4、依赖升级

Spring Boot 3.2.0 迁移到以下Spring项目的新版本:

  • Spring AMQP 3.1
  • Spring Authorization Server 1.2
  • Spring Batch 5.1
  • Spring Data 2023.1
  • Spring Framework 6.1
  • Spring HATEOAS 2.2
  • Spring Integration 6.2
  • Spring Kafka 3.1
  • Spring LDAP 3.2
  • Spring Pulsar 1.0
  • Spring Retry 2.0
  • Spring Security 6.2
  • Spring Session 3.2

第三方依赖也已更新,更值得注意的是以下内容:

  • Artemis 2.29
  • Brave 5.16
  • Elasticsearch Client 8.10
  • Flyway 9.22
  • GraphQL Java 21.1
  • Hibernate 6.3
  • JUnit 5.10
  • Jedis 5.0
  • Kafka 3.6
  • Kotlin 1.9
  • Liquibase 4.24
  • Log4j 2.21
  • MariaDB 3.2
  • Micrometer 1.12
  • Micrometer Tracing 1.2
  • Mockito 5.4
  • Mongo Java Driver 4.11
  • MySQL 8.1
  • Neo4j Java Driver 5.10
  • OkHttp 4.12
  • OpenTelemetry 1.28
  • Oracle UCP 23.3
  • Rabbit AMQP Client 5.18.0
  • Rabbit Stream Client 0.11
  • Reactor 2023.0
  • Selenium 4.14
  • SnakeYAML 2.2

5、弃用项

  • OkHttp 3支持已被弃用,取而代之的是OkHttp 4
  • 不赞成使用context.initializer.classes环境属性注册其他ApplicationContextInitializer,而赞成以程序方式或在spring.factories中注册每个委托。
  • 不赞成使用context.listener.classes环境属性注册其他ApplicationListener,而赞成用程序或在spring.factories中注册每个委托。
  • 对InfluxDB的支持已被弃用,取而代之的是新的InfluxDB Java客户端及其自己的SpringBoot集成。
  • TaskExecutorBuilder已被弃用,取而代之的是ThreadPoolTaskExecutorBuilder。
  • TaskSchedulerBuilder已被弃用,取而代之的是ThreadPoolTaskSchedulerBuilder。
  • ThreadPoolTaskExecutorCustomizer替代TaskExecutorCustomizer
  • ThreadPoolTaskSchedulerBuilder替代TaskSchedulerBuilder
  • ThreadPoolTaskSchedulerCustomizer替代TaskSchedulerCustomizer
  • 弃用NettyWebServer中一些过时的构造函数

总结

SpringBoot 3.2 是一个比较重要的版本,尤其是对虚拟线程的支持,可以说和 Java 21 遥相呼应。

感兴趣的xdm,其实已经可以开始尝试使用一下了。

但在生产项目还是不建议使用哈,因为配套的一些基础设施还没有完全兼容,需要更多人踩坑才行哦。

总之,这是一个比较有意义的版本。

公众号 --> 【Java分享客栈】


如果喜欢,请点赞+关注↑↑↑,持续分享干货哦~