新特性和改进
1、Java 17 基线和 Java 19 支持:Spring Boot 3.0 需要 Java 17 作为最低版本,并且已针对 JDK 19 进行了测试
2、GraalVM 基线和原生构建工具:需要 GraalVM 22.3 或更高版本以及 Native Build Tools Plugin 0.9.17 或更高版本
Spring Boot 3.0 引入了对 GraalVM 原生镜像的官方支持,这是一项重大的改进,它允许将 Spring Boot 应用程序转换为 GraalVM 原生镜像,从而提供显著的内存和启动性能改进。
为了使用这一特性,你需要确保满足以下条件:
GraalVM 版本
Spring Boot 3.0 需要 GraalVM 22.3 或更高版本。这是因为 GraalVM 22.3 引入了对 Java 17 的支持,并且提供了必要的工具来构建原生镜像 。
Native Build Tools Plugin
需要 Native Build Tools Plugin 0.9.17 或更高版本。这个插件为 Maven 和 Gradle 提供了支持,以便执行包括生成原生镜像在内的各种 GraalVM 任务 。
环境配置
安装完 GraalVM 后,需要配置环境变量,确保 GRAALVM_HOME
环境变量指向 GraalVM 的安装目录,并将 <GRAALVM_HOME>/bin
添加到系统的 PATH
变量中。这样,你就可以在命令行中直接使用 native-image
命令和其他 GraalVM 工具 。
构建工具
对于 Maven 用户,需要在项目中包含 org.graalvm.buildtools:native-maven-plugin
插件,并激活 native
Profile 来构建原生镜像。对于 Gradle 用户,则需要应用 Native Build Tools Gradle 插件 。
原生镜像构建
使用 GraalVM Native Build Tools,你可以直接在不使用 Docker 的情况下生成原生可执行文件。无论是使用 Maven 还是 Gradle,都可以通过相应的插件来执行这一过程 。
系统要求
在 Windows 系统上,你可能需要安装 Visual Studio 和 Microsoft Visual C++ (MSVC) 作为本地编译环境,因为编译原生镜像需要依赖于平台特定的编译器 。
GraalVM 特性
GraalVM 提供了包括高级优化即时编译器、原生镜像预编译、多语言支持等特性,这些都可以帮助你提升应用性能并降低基础设施成本 。
第三方库升级:基于并需要 Spring Framework 6,以及其他多个 Spring 项目的升级版本
以下是一些关键的第三方库升级信息:
Spring Framework 6
Spring Boot 3.0 基于 Spring Framework 6,这是对 JDK 的要求是最低也得是 Java 17,对于 Java EE 的要求是最低也得是 Jakarta EE 9。
Spring AMQP 3.0
这是 Spring 对于消息总线的更新版本,提供了对新版本 RabbitMQ 客户端的更好支持。
Spring Batch 5.0
这是 Spring 对于批处理操作的更新版本,引入了对最新批处理需求的支持。
Spring Data 2022.0
这是 Spring Data 项目的更新版本,提供了对各种数据库和存储系统的更好支持。
Spring Kafka 3.0
这是 Spring 对于 Apache Kafka 的更新版本,提供了对 Kafka 新版本的更好支持。
Spring Security 6.0
这是 Spring Security 的更新版本,提供了更好的安全性和稳定性。
Spring WebFlux
这是 Spring 对于响应式编程的更新版本,提供了对最新 WebFlux 规范的支持。
其他 Spring 项目
包括 Spring GraphQL 1.1、Spring HATEOAS 2.0、Spring Integration 6.0、Spring LDAP 3.0、Spring REST Docs 3.0、Spring Retry 2.0、Spring Session 2022.0、Spring WS 4.0 等都进行了相应的升级。
第三方库
包括但不限于 Couchbase Client 3.4、Elasticsearch Client 8.5、Flyway 9、Groovy 4.0、Hibernate 6.1、Jackson 2.14、Jersey 3.1、Jetty 11、jOOQ 3.16、Kotlin 1.7.20、Liquibase 4.13、Lettuce 6.2、Log4j 2.18、Logback 1.4、Micrometer 1.10、Micrometer Tracing 1.0、Neo4j Java Driver 5.2、Netty 4.1.77.Final、OkHttp 4.10、R2DBC 1.0、Reactor 2022.0、SLF4J 2.0 等。
从 Java EE 迁移到 Jakarta EE APIs:选择了与 Jakarta EE 10 兼容的依赖项
-
依赖项更新:Spring Boot 3.0 已将所有底层依赖项从 Java EE 迁移到了 Jakarta EE API,基于 Jakarta EE 9 并尽可能地兼容 Jakarta EE 10。包括但不限于以下依赖项的更新:
- Jakarta Activation 2.1
- Jakarta JMS 3.1
- Jakarta JSON 2.1
- Jakarta JSON Bind 3.0
- Jakarta Mail 2.1
- Jakarta Persistence 3.1
- Jakarta Servlet 6.0
- Jakarta Servlet JSP JSTL 3.0
- Jakarta Transaction 2.0
- Jakarta Validation 3.0
- Jakarta WebSocket 2.1
- Jakarta WS RS 3.1
- Jakarta XML SOAP 3.0
- Jakarta XML WS 4.0
-
代码和配置修改:由于包名从
javax.*
更改为jakarta.*
,需要更新代码中的所有相关引用,包括导入语句、类名和 API 调用。此外,还需要调整pom.xml
、server.xml
等配置文件中的相关配置。
Log4j2 增强功能:提供了新的扩展,包括环境属性查找和系统属性支持
Log4j2 引入了多种增强功能,其中包括对环境属性查找和系统属性支持的扩展。这些增强使得 Log4j2 在配置和使用上更加灵活和强大。
环境属性查找
Log4j2 支持通过 ${env:ENV_NAME}
语法来引用系统环境变量。这允许开发者在配置文件中插入动态值,例如获取部署环境的具体信息。此外,还支持为环境变量提供默认值,如 ${env:ENV_NAME:-default_value}
,如果环境变量未设置,则使用默认值。
系统属性支持
Log4j2 还支持通过 ${sys:some.property}
语法来引用系统属性。这为配置提供了额外的灵活性,允许开发者在不改变代码的情况下,通过系统属性来调整日志行为。系统属性也可以设置默认值,如 ${sys:some.property:-default_value}
。
属性替换
Log4j2 的配置文件中可以使用属性占位符,这些占位符在启动时会被实际的值替换。例如,可以在配置文件中设置一个属性 Console
,并在运行时通过系统属性来决定使用哪个 Appender。
Spring 环境属性增强
Log4j2 支持在配置中引用 Spring 环境中的属性,使用 Spring:
前缀。例如,${spring:spring.application.name}
可以获取 Spring 应用的名称。
系统属性增强
Log4j2 现在支持更多可配置的 System.properties
。例如,可以使用 log4j2.skipJansi
系统属性来配置 Console Appender 是否在 Windows 上使用 Jansi 输出流。在 Log4j2 初始化之后加载的所有 System.properties
都可以从 Spring Environment 拿到。例如,可以把 log4j2.skipJansi = false
配置到 application.properties
中。
无垃圾机制
从版本 2.6 开始,Log4j2 默认以“无垃圾”模式运行,尽可能重用对象和缓冲区,减少临时对象的分配,提高性能。
性能提升
Log4j2 通过重用 ThreadLocal 字段中的对象和内存缓冲区,减少了临时对象的数量,从而提高了性能。
系统属性控制
Log4j2 提供了系统属性来控制无垃圾机制的行为,如 log4j2.enableThreadlocals
和 log4j2.enableDirectEncoders
。
@ConstructorBinding 检测改进:如果类只有一个参数化构造函数,则不再需要 @ConstructorBinding 注解
@ConstructorBinding 是 Spring Framework 5.3 中引入的一个注解,用于指示 Spring 应该使用类的构造函数来绑定和创建对象,而不是使用 setter 方法或 public 字段。这在处理不可变对象或需要精确控制对象创建过程时非常有用。
改进内容
在 Spring Framework 6 和 Spring Boot 3.0 之前,如果你的类只有一个参数化的构造函数,你需要使用 @ConstructorBinding
注解来明确告诉 Spring 使用这个构造函数进行数据绑定。例如:
import org.springframework.binding.annotation.ConstructorBinding;
@ConstructorBinding
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
改进后的行为
在 Spring Framework 6 和 Spring Boot 3.0 中,如果一个类只有一个参数化的构造函数,Spring 会自动检测并使用这个构造函数进行数据绑定,而不需要显式地添加 @ConstructorBinding
注解。上面的代码可以简化为:
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
Micrometer 更新:支持 Micrometer 1.10 中引入的新观测 API,以及对 Micrometer 跟踪的自动配置
Micrometer 是一个应用度量(metrics)的库,用于在微服务架构中监控和观测应用性能。它提供了一个与平台无关的 API,可以用来度量各种应用指标,如 CPU 使用率、内存使用量、请求计数、请求延迟等,并将这些指标数据发送到多种监控系统,如 Prometheus、Graphite、Datadog、InfluxDB、Wavefront 等。
以下是一些关键的更新:
支持 Micrometer 1.10
Spring Boot 3.0 支持集成 Micrometer 1.10 及以上版本,引入了全新的观测 API。这包括对 Brave、OpenTelemetry、Zipkin 和 Wavefront 组件的支持。使用 Micrometer 可观测 API 时,可以主动将观测数据报告给 Zipkin 等组件,并支持自定义追踪参数配置,这有助于更好地监控应用的健康状况 。
Observation API
Micrometer 1.10 引入了 ObservationRegistry
,它提供了一个 API 来创建度量和追踪数据。Spring Boot 3.0 现在会自动装配 ObservationRegistry
实例,并可以使用 ObservationRegistryCustomizer
进一步定制化 ObservationRegistry
。
Micrometer Tracing 自动配置
Spring Boot 3.0 现在自动配置 Micrometer Tracing,包括对 Brave、OpenTelemetry、Zipkin 和 Wavefront 的支持。此外,当引入 io.micrometer:micrometer-registry-otlp
包之后,OtlpMeterRegistry
也会自动配置 。
Prometheus 支持
如果存在 Prometheus 依赖和 Tracer Bean,Spring Boot 3.0 将自动装配 SpanContextSupplier
,它会把度量数据关联到追踪中,它会把当前的 traceID 和 spanID 保存到 Prometheus 的 Example 中 。
更灵活的 Spring Data JDBC 自动配置:现在可以替换多个自动配置的 Bean
以下是一些可以替换的 Bean 类型:
- org.springframework.data.jdbc.core.JdbcAggregateTemplate:用于处理聚合操作的模板。
- org.springframework.data.jdbc.core.convert.DataAccessStrategy:定义数据访问策略,如保存、删除操作。
- org.springframework.data.jdbc.core.convert.JdbcConverter:用于转换数据库类型和 Java 类型。
- org.springframework.data.jdbc.core.convert.JdbcCustomConversions:自定义类型转换。
- org.springframework.data.jdbc.core.mapping.JdbcMappingContext:用于 JDBC 的映射上下文,处理实体和数据库表之间的映射。
- org.springframework.data.relational.RelationalManagedTypes:管理关系型数据库中的类型。
- org.springframework.data.relational.core.dialect.Dialect:数据库方言,用于处理不同数据库的特定 SQL 方言。
支持 Elasticsearch Java 客户端:引入了新的 Elasticsearch Java 客户端的自动配置
Spring Boot 3.0 引入了对 Elasticsearch Java API Client 的自动配置,推荐使用该客户端进行与 Elasticsearch 的交互。这个客户端提供了更高层次的抽象,简化了与 Elasticsearch 的通信。
自动配置
通过引入 spring-boot-starter-data-elasticsearch
依赖,Spring Boot 会自动配置与 Elasticsearch 相关的 Bean,例如 ElasticsearchRestTemplate
和 ElasticsearchClient
。你可以通过 spring.elasticsearch.*
属性来配置连接信息,如集群地址、用户名和密码等。
配置示例
在 application.yml
或 application.properties
中,可以配置如下:
spring:
elasticsearch:
uris: http://localhost:9200
username: user
password: secret
使用示例
配置完成后,可以通过自动装配的 ElasticsearchRestTemplate
来执行各种操作,例如索引、搜索等:
@Autowired
private ElasticsearchRestTemplate elasticsearchTemplate;
public List<Book> searchBooks(String query) {
Query searchQuery = new NativeSearchQueryBuilder()
.withQuery(QueryBuilders.queryStringQuery(query))
.build();
return elasticsearchTemplate.queryForList(searchQuery, Book.class);
}
自动配置 JdkClientHttpConnector:如果没有其他 HTTP 客户端可用,现在将自动配置 JdkClientHttpConnector
JdkClientHttpConnector 是 Spring Framework 6.0 版本中引入的一个类,它实现了 ClientHttpConnector 接口,用于连接到目标服务器并提供必要的基础设施来发送 ClientHttpRequest 和接收 ClientHttpResponse。这个连接器允许 Spring 的 WebClient 与 JDK 的 HttpClient 一起使用,提供了一种反应式的HTTP客户端连接方式。
JdkClientHttpConnector 提供了几种构造函数,可以无参构造,也可以传入一个 HttpClient 实例或一个预初始化的 HttpClient.Builder 和 JdkHttpClientResourceFactory 实例来构造。它还提供了 setBufferFactory 方法来设置缓冲区工厂,以及 connect 方法来连接到服务器。
在 Spring Framework 中,如果没有 Netty Reactor、Jetty reactive client 和 Apache HTTP client,JdkClientHttpConnector 将被自动装配,这使得 WebClient 可以与 JDK 的 HttpClient 配合使用。
此外,JdkClientHttpConnector 还支持异步请求,可以利用非阻塞的特性来提高效率。在性能测试中,使用 JDK HttpClient 的异步模式相比于同步模式或其他客户端库(如 Apache HttpClient)在线程数相同的情况下,效率有显著提升。
使用示例
要使用 JdkClientHttpConnector
,你只需确保在项目中没有引入其他 HTTP 客户端依赖。以下是一个简单的配置示例:
添加依赖
在 pom.xml
中添加 Spring Boot Web 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
使用 WebClient
你可以通过 WebClient
来发起 HTTP 请求,例如:
import org.springframework.web.reactive.function.client.WebClient;
@Bean
public WebClient webClient() {
return WebClient.builder()
.baseUrl("http://localhost:8080")
.clientConnector(new JdkClientHttpConnector())
.build();
}
发起请求
使用 WebClient
发起请求
webClient.get()
.uri("/api/resource")
.retrieve()
.bodyToMono(String.class)
.subscribe(response -> System.out.println(response));
@SpringBootTest 与主方法一起使用:@SpringBootTest 注解现在可以使用任何发现的 @SpringBootConfiguration 类的主方法
在 Spring Boot 3.0 之前,@SpringBootTest
注解通常与带有 @SpringBootApplication
注解的主类一起使用,因为 @SpringBootApplication
包含了 @SpringBootConfiguration
,而 @SpringBootTest
会查找带有 @SpringBootConfiguration
注解的类。
从 Spring Boot 3.0 开始,@SpringBootTest
注解得到了增强,现在可以使用任何发现的 @SpringBootConfiguration
类的主方法,而不仅仅是带有 @SpringBootApplication
注解的类。这意味着你可以有多个配置类,每个类都有自己的主方法,并且可以针对每个配置类单独编写测试。
使用示例
假设你有一个 Spring Boot 应用,它包含两个配置类,每个类都有自己的主方法:
@SpringBootConfiguration
public class FirstApplication {
public static void main(String[] args) {
SpringApplication.run(FirstApplication.class, args);
}
}
@SpringBootConfiguration
public class SecondApplication {
public static void main(String[] args) {
SpringApplication.run(SecondApplication.class, args);
}
}
现在,你可以简单地使用 @SpringBootTest
注解,而不需要指定类,Spring Boot 会自动发现并使用 FirstApplication
的主方法:
@RunWith(SpringRunner.class)
@SpringBootTest
public class FirstApplicationTests {
// ...
}
如果你有多个配置类,并且想要针对特定的配置类编写测试,你可以使用 @SpringBootTest
注解的 classes
属性来指定:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SecondApplication.class)
public class SecondApplicationTests {
// ...
}
弃用和移除
- @ConstructorBinding 移动:从
org.springframework.boot.context.properties
包移动到org.springframework.boot.context.properties.bind
。 - JsonMixinModule 扫描基于构造函数:已被弃用。
- ClientHttpRequestFactorySupplier 应被替换:应使用 ClientHttpRequestFactories。
- 不再支持 Cookie comment 属性。
- RestTemplateExchangeTagsProvider 等被替换:被 ObservationConvention 等价物替换。
- HealthContributor @Configuration 无参构造函数已被弃用。
- DefaultTestExecutionListenersPostProcessor 等被弃用:被 Spring Framework 的 ApplicationContextFailureProcessor 替代。
- 管理指标导出属性被弃用:被
management.<product>.metrics.export
替代。 - Prometheus 指标导出的推送设置:被
post
替代。 - @AutoConfigureMetrics 被弃用:被 @AutoConfigureObservability 替代。
其他变更
- 启动期间不再记录主机名,以提高启动速度。
- 移除了对 Java SecurityManager 的支持。
- 移除了对 Spring Framework CommonsMultipartResolver 的支持。
- 提供了多种属性和配置的微调。