⭐ 新特性 ArithmeticException:在 @Scheduled(fixedDelay = Long.MAX_VALUE, timeUnit = TimeUnit.MINUTES) 上 long 溢出 #31210 对 RequestResponseBodyMethodProcessor 中的 resolveArgument 方法进行优化 #31175 更新 BeanValidationBeanRegistrationAotProcessor 中 validation exception 的日志级别 #31147 跳过在 PathMatchingResourcePatternResolver 中搜索不存在的目录。#31111 在 Argument[Type]PreparedStatementSetter 的 doSetValue() 中为 argValue 添加 @Nullable #31086 优化 StringUtils 中的 whitespace 检查 #31067 使用 simple JPARepository 时缺少代理提示 #31050 为 ReactiveAdapterRegistry 中的现有 adapter 注册 override #31047 DefaultListableBeanFactory#getBeanNamesForType 在解析 FactoryBean 时未考虑目标类型 #30987 让 spring-core 访问 org.jboss.vfs,以便在 WildFly 上支持 VfsUtils #30973 当 contentLength 可用时,在 StringHttpMessageConverter 中使用 readNBytes #30942 当数组长度不大于 1 时,跳过数组排序 #30934 避免对每个 SseEventBuilder 条目进行刷新 #30912 使用 protected 修饰 DefaultGenerationContext(DefaultGenerationContext, String) 构造函数 #30895 在 Spring MVC 中的 AbstractResourceResolver 子类中添加缺失的 @Nullable 注解 #30893 创建 scope Bean 实例时的性能瓶颈 #30883 对同一 Bean 类中的多个 @Autowired 方法进行确定性的 Bean 初始化 #30359 优化 ClassUtils#getMostSpecificMethod #30272 Hibernate native 查询代理缺少 native 提示 #29603 检查异常原因以支持 @PropertySource(ignoreResourceNotFound) #22276 调整 PayloadMethodArgumentResolver 中的验证元数据处理方式 #21852 🐞 Bug 修复 Spring Boot 启动失败 does not reside in the file system: manifoldclass://622488023/.
1、概览 本文将会带你学习在 Spring 应用中实现 Kafka Consumer 重试消费的 2 种方式,及其优缺点。
关于如何在 Spring 中整合 Kafka 的细节,请参阅 这里。
2、项目设置 创建一个新的 Spring Boot 项目,并添加 spring-kafka 依赖:
<dependency> <groupId>org.springframework.kafka</groupId> <artifactId>spring-kafka</artifactId> <version>3.0.1</version> </dependency> 创建一个对象:
public class Greeting { private String msg; private String name; // 构造函数、get、set 方法省略 } 3、Kafka Consumer Kafka Consumer(消费者)是从 Kafka 集群中读取数据的客户端应用程序。它订阅一个或多个 topic,并消费已发布的消息。Producer (生产者)向 topic 发送消息,topic 是存储和发布记录的类别名称。topic 被分为多个分区,以便横向扩展。每个分区都是一个不可更改的消息序列。
Consumer 可以通过指定偏移量(即消息在分区中的位置)来读取特定分区中的消息。Ack(确认)是消费者发送给 Kafka broker 的消息,表示它已成功处理了一条记录。一旦 ACK 被发送,消费者偏移量(consumer offset)将会被更新。
这将确保消息已被消费,并且不会再次传递给当前 Listener。
3.1、Ack 模式 Ack 模式决定了 broker 何时更新消费者偏移量(consumer offset)。
1、概览 MutlipartFile 是 Spring 提供的一个接口,用于接收 multipart 请求中的文件参数。Spring 没有为其提供任何默认实现,但提供了一个用于测试的实现。
在本教程中,我们将学习如何将字节数组转换为 MultipartFile。
2、实现 MultipartFile 接口 让我们创建自己的 MultipartFile 接口实现,并封装传入的字节数组:
public class CustomMultipartFile implements MultipartFile { private byte[] input; @Override public String getName() { return null; } @Override public String getOriginalFilename() { return null; } @Override public String getContentType() { return null; } // 下一个代码段中定义了接口的其他方法 } 我们在类中定义了一个 byte[] 属性,存储传入的字节数组。接口中定义的其他几个描述性方法,可以根据需求来实现。这里默认返回 null。
剩余的几个接口方法是必须要实现的,如下:
public class CustomMultipartFile implements MultipartFile { // 前一段儿代码省略... @Override public boolean isEmpty() { return input == null || input.
1、概览 Spring 6 提供了一项新功能,有望优化应用程序的性能: Ahead-of-Time(AOT) 编译支持。
在本文中,我们将了解 Spring 6 中 AOT 优化功能的工作原理、优点以及使用方法。
2、AOT 编译 2.1、JIT 编译器 对于最常用的 Java 虚拟机(JVM),如 Oracle 的 HotSpot JVM 和 OpenJDK,当我们编译源代码(.java 文件)时,生成的字节码存储在 .class 文件中。这样,JVM 就会使用 JIT(Just-In-Time,即时编译) 编译器将字节码转换为机器码。
此外,JIT 编译涉及 JVM 对字节码的解释,以及在运行时将频繁执行的代码动态编译为本地机器码。
2.2、AOT 编译器 Ahead-of-Time(AOT,提前编译或预编译)是一种在应用程序运行前将字节码预编译为本地机器码的技术。
Java 虚拟机(JVM)通常不支持这一功能。不过,甲骨文已在 OpenJDK 项目中发布了一项针对 HotSpot JVM 的实验性 AOT 功能,名为 “GraalVM Native Image”,允许进行 AOT 编译。
预编译代码后,计算机处理器可直接执行代码,无需 JVM 解释字节码,从而缩短了启动时间。
关于 AOT 编译器的更多细节可以参考 官方文档。
3、Spring 6 中的 AOT 支持 3.1、AOT 编译优化 在构建 Spring 6 应用程序时,我们需要考虑三种不同的运行时选项:
1、概览 日志是系统中的一个重要组件。Spring Boot 支持 Logback 和 Log4j2 日志框架,并且提供了一些扩展,可用于高级配置。
在本教程中,我将带你学习如何在 Spring Boot 中使用 Logback 和 Log4j2 的扩展进行高级的日志配置。
2、Logback 扩展 Spring Boot 默认使用 Logback 进行日志记录。在本节中,我们将了解 Logback 的一些扩展,以进行高级配置。
注意:Spring Boot 建议使用 logback-spring.xml 作为 Logback 的配置文件名称,而不是默认的 logback.xml。因为 logback.xml 配置文件会被 Logback 默认加载,它会比 Spring 更早地加载进系统,所以我们不能在标准的 logback.xml 中使用扩展,
2.1、Maven 依赖 要使用 Logback,我们需要在 pom.xml 中添加 logback-classic 依赖项。
spring-boot-starter-web 依赖已经包含了它,所以不需要额外导入 logback-classic:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> 2.2、基本日志 首先,在 Spring Boot main 类中输出一些示例日志:
@SpringBootApplication public class SpringBootLogbackExtensionsApplication { private static final Logger logger = LoggerFactory.
SameSite 是一个用于增强 Web 应用程序安全性的 Cookie 机制。它定义了浏览器在发送跨站请求时是否应该附加 Cookie。旨在防止跨站请求伪造(CSRF)攻击和某些类型的跨站信息泄露攻击。
SameSite 属性是可选的,它有三个可选值:
Strict(严格模式):在严格模式下,浏览器只会在用户访问与 Cookie 关联的站点时发送 Cookie。如果请求来自其他站点(包括跨站请求),浏览器将不会发送 Cookie。这样可以有效地防止跨站请求伪造攻击。
Lax(宽松模式):在宽松模式下,大多数情况下,浏览器只会在用户访问与 Cookie 关联的站点时发送 Cookie。但是,如果用户从外部站点通过 GET 方法访问当前站点的 URL,浏览器会发送 Cookie。这样可以在某些常见的使用情况下保持用户体验,同时仍然提供一定程度的安全性。总结如下:
请求类型 示例 正常情况 Lax 链接 <a href=...></a> 发送 Cookie 发送 Cookie 预加载 <link rel=prerender href=.../> 发送 Cookie 发送 Cookie GET 表单 <form method=GET action=...> 发送 Cookie 发送 Cookie POST 表单 <form method=POST action=...> 发送 Cookie 不发送 iframe <iframe src=...></iframe> 发送 Cookie 不发送 AJAX $.get(...) 发送 Cookie 不发送 Image <img src=.
1、概览 在 Spring 6 和 Spring Boot 3 中,我们可以使用 Java 接口来定义声明式的远程 HTTP 服务。这种方法受到 Feign 等流行 HTTP 客户端库的启发,与在 Spring Data 中定义 Repository 的方法类似。
在本教程中,我们将首先了解如何定义 HTTP 接口,以及可用的 exchange 方法注解和支持的方法参数和返回值。接着,学习如何创建一个实际的 HTTP 接口实例,即执行所声明 HTTP exchange 的代理客户端。
最后,我们将介绍如何对声明式 HTTP 接口及其代理客户端进行异常处理和测试。
2、HTTP 接口 声明式 HTTP 接口包括用于 HTTP exchange 的注解方法。我们可以通过使用带注解的 Java 接口来简单地表达远程 API 的细节,然后让 Spring 生成实现该接口并执行 exchange 的代理。这有助于减少样板代码的编写。
2.1、Exchange 方法 @HttpExchange 是我们可以应用于 HTTP 接口及其 exchange 方法的根注解。如果我们将其应用于接口层,那么它就会应用于所有 exchange 方法。这对于指定所有接口方法的共同属性(如 content type 或 URL 前缀)非常有用。
所有 HTTP 方法都有对应的注解:
@GetExchange 用于 HTTP GET 请求。 @PostExchange 用于 HTTP POST 请求。 @PutExchange 用于 HTTP PUT 请求。 @PatchExchange 用于 HTTP PATCH 请求。 @DelectExchange 用于 HTTP DELETE 请求。 让我们使用不同的 HTTP 方法注解,来为远程 API 定义一个声明式的 HTTP 接口:
1、概览 在本教程中,我们将学习如何在 Spring Boot 应用中整合 OpenTelemetry 。以及如何配置 OpenTelemetry 来追踪请求链路,并将其发送到中央系统以监控请求。
2、OpenTelemetry 简介 OpenTelemetry(Otel)是一组标准化的工具(与供应商无关)、API 和 SDK。它是一个 CNCF 孵化项目,是 OpenTracing 和 OpenCensus 项目的合并产物。
OpenTracing 用于向可观测性后端发送 telemetry(遥测)数据。OpenCensus 项目提供了一套特定于语言的库,开发人员可以用它来检测自己的代码,并将其发送到任何受支持的后端。Otel 使用与其前身项目相同的 trace 和 span 概念来表示微服务间的请求链路。
OpenTelemetry 允许我们检测、生成和收集 telemetry 数据,这有助于分析应用程序的行为或性能。telemetry 数据包括日志、指标和链路跟踪。
使用 Otel SDK,我们可以轻松地覆盖或添加更多属性到链路跟踪中。
让我们通过一个例子来深入了解一下。
3、示例应用 假设我们需要构建两个微服务,其中一个服务与另一个服务交互。
3.1、Maven 依赖 首先,我们将创建 Spring Boot Web 项目,并在两个应用中包含以下 Spring 和 OpenTelemetry 依赖项:
spring-cloud-starter-sleuth、spring-cloud-sleuth-otel-autoconfigure 和 opentelemetry-exporter-otlp 将自动捕获链路跟踪并导出到任何支持的 collector。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> <exclusions> <exclusion> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-sleuth-brave</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.
1、概览 在这本教程中,我们将了解如何在 Spring 应用中获取当前的 ApplicationContext。
2、ApplicationContext ApplicationContext 代表 Spring IoC 容器,其中包含应用程序创建的所有 Bean。它负责实例化、配置和创建 Bean。此外,它还从 XML 或 Java 中提供的配置元数据中获取 Bean 的信息。
ApplicationContext 是 BeanFactory 的子接口。除了 BeanFactory 的功能外,它还包括消息解析和国际化、资源加载和事件发布等功能。此外,它还具有加载多个 context 的功能。
每个 Bean 都是在容器启动后实例化的。
我们可能希望使用此容器访问应用中的其他 Bean 和资源。我们将学习两种在 Spring 应用中获取当前 ApplicationContext 的方法。
3、ApplicationContext Bean 获取当前 ApplicationContext 的最简单方法是使用 @Autowired 注解将其注入到我们的 Bean 中。
首先,声明实例变量,并使用 @Autowired 对其进行注解:
@Component public class MyBean { @Autowired private ApplicationContext applicationContext; public ApplicationContext getApplicationContext() { return applicationContext; } } 也可以使用 @Inject 来代替 @Autowired。
Spring Boot 3.0 已于 2022 年 11 月底全面 发布。本文将教你如何使用 Spring Boot 3 和 Spring Cloud 组件构建微服务。
总的来说,本文将涉及以下主题:
在云原生开发中使用 Spring Boot 3。 使用 Spring Cloud Netflix Eureka 为所有微服务提供服务发现功能。你可能想说 “在还用 Eureka?” - 是的,Eureka 还在。它是 Spring Cloud 中最后一个可用的 Netflix 微服务组件。 使用 Spring Cloud OpenFeign 进行服务间通信。 使用 Spring Cloud Config 作为分布式配置中心。 使用 Spring Cloud Gateway 作为网关,其中包括使用 Springdoc 项目创建全局 OpenAPI 文档。 使用 Micrometer OpenTelemetry 和 Zipkin 采集链路追踪。 从 Spring Boot 2 迁移到 Spring Boot 3 并不是太麻烦,具体变更的细节和迁移方法可以参考 这篇文章。