1、概览 动态管理应用程序配置是许多实际应用场景中的关键要求。在微服务架构中,由于扩展操作或负载条件的变化,不同的服务可能需要即时更改配置。在其他情况下,应用程序可能需要根据用户偏好、来自外部 API 的数据调整其行为,或满足动态变化的要求。
application.properties 文件是静态的,在不重启应用的情况下无法更改。不过,Spring Boot 提供了几种强大的方法,可在运行时调整配置而无需停机。无论是在实时应用程序中切换功能、更新数据库连接以实现负载均衡,还是在不重新部署应用的情况下更改第三方集成的 API Key,Spring Boot 的动态配置功能都能为这些复杂的环境提供所需的灵活性。
本文将带你了解几种无需直接修改 application.properties 文件即可动态更新 Spring Boot 应用程序中属性的策略。这些方法可满足不同的需求,从非持久性内存更新到使用外部文件进行持久性更改。
本文中的示例使用 Spring Boot 3.2.4、JDK17 以及 Spring Cloud 4.1.3。不同版本的 Spring Boot 可能需要对代码进行轻微调整。
2、使用 Prototype Scope Bean 当我们需要动态调整特定 Bean 的属性,而不影响已创建的 Bean 实例或更改全局应用程序状态时,一个简单的使用 @Value 直接注入的 @Service 类是不够的,因为这些属性在 Application Context 的生命周期内是静态的。
相反,可以使用 @Configuration 类中的 @Bean 方法创建具有可修改属性的 Bean。这种方法允许在应用程序执行过程中动态更改属性:
@Configuration public class CustomConfig { @Bean @Scope("prototype") // Scope 为 prototype public MyService myService(@Value("${custom.property:default}") String property) { return new MyService(property); } } 通过使用 @Scope("prototype") 注解,我们可以确保每次调用 myService(.
日志记录是应用故障排除的重要组成部分,也是可观测性的三大支柱之一,另外两个是指标和追踪(Trace)。没有人喜欢在生产环境中瞎操作,当事故发生时,开发者会很乐意看到日志文件。日志通常以人类可读的格式输出。
结构化日志是一种技术,其中日志输出以定义良好的格式编写,通常是机器可读的。这种格式可以输入到日志管理系统中,从而实现强大的搜索和分析功能。结构化日志最常用的格式之一是 JSON。
Spring Boot 3.4 开箱即支持结构化日志。它支持 Elastic Common Schema(ECS)和 Logstash 格式,也可以使用自己的格式进行扩展。
结构化日志的 Hello World 在 start.springboot.io 上创建一个新项目,不需要添加任何依赖,但至少要选择 Spring Boot 3.4.0-M2。
要在控制台上启用结构化日志记录,请将如下配置添加到 application.properties 中:
logging.structured.format.console=ecs 这将指示 Spring Boot 以 Elastic Common Schema(ECS) 格式输出日志。
启动应用,你就会看到日志是 JSON 格式的:
{"@timestamp":"2024-07-30T08:41:10.561295200Z","log.level":"INFO","process.pid":67455,"process.thread.name":"main","service.name":"structured-logging-demo","log.logger":"com.example.structured_logging_demo.StructuredLoggingDemoApplication","message":"Started StructuredLoggingDemoApplication in 0.329 seconds (process running for 0.486)","ecs.version":"8.11"} 将结构化日志记录到文件 你还可以将结构化日志写入文件。例如,这可以用于在控制台上打印人类可读的日志,同时将结构化日志写入文件以供机器读取。
要启用此功能,请将如下配置添加到 application.properties 中,并确保删除 logging.structured.format.console=ecs 设置:
logging.structured.format.file=ecs logging.file.name=log.json 现在启动应用,你会看到控制台上有人类可读的日志,而 log.json 文件则包含机器可读的 JSON 内容。
添加额外字段 结构化日志的一个强大功能是,开发人员可以以结构化的方式在日志事件中添加信息。例如,你可以在每个日志事件中添加用户 ID,然后根据该 ID 进行过滤,查看这个特定用户做了什么。
Elastic Common Schema 和 Logstash 都在 JSON 中包含了 Mapped Diagnostic Context 的内容。
Spring Boot v3.3.3 发布了。
⭐ 新特性 在 JavaVersion 枚举中添加 TWENTY_THREE #41716 🐞 Bug 修复 继承 DefaultErrorAttributes 并覆写 getErrorAttributes() 会被调用两次 #41995 在使用 WebFlux 时,当 ResponseStatusException 的原因是 BindingResult 异常时,server.error.include-binding-errors=ALWAYS 不生效 #41987 将 BOOT-INF/lib 中的 jar 添加到 classpath 时,PropertiesLauncher 不遵循 classpath.idx #41970 /cloudfoundryapplication 下 SBOM 端点的 Web 扩展不可用 #41890 启动器(Launcher)的 ClassLoader 不再具有并行功能 #41873 spring-boot-testcontainers 会在 AOT 处理过程中导致不必要的容器初始化 #41859 当 Reactor 不在类路径上时,ReactiveElasticsearchRepositoriesAutoConfiguration 应关闭 #41678 当 classifier 设置为非默认值时,mvn spring-boot:build-image 失败 #41661 Spring Boot Maven 插件 AOT 无法使用 module-info.
1、概览 无论是用户注册、密码重置还是促销活动,发送电子邮件都是现代 Web 应用的一项重要功能。
本文将带你了解如何在 Spring Boot 应用中使用 SendGrid 发送电子邮件。
2、SendGrid 设置 在开始之前,我们首先需要一个 SendGrid 账户。SendGrid 提供了免费套餐,允许我们每天发送多达 100 封电子邮件,这对于演示来说已经足够了。
注册完成后,需要创建一个 API Key 来对我们发送到 SendGrid 服务的请求进行 身份认证。
3、项目设置 在开始使用 SendGrid 发送电子邮件之前,需要添加 SDK 依赖并配置应用。
3.1、依赖 首先,在项目的 pom.xml 文件中添加 SendGrid SDK 依赖:
<dependency> <groupId>com.sendgrid</groupId> <artifactId>sendgrid-java</artifactId> <version>4.10.2</version> </dependency> 该依赖为我们提供了与 SendGrid 服务交互和从应用发送电子邮件所需的类。
3.2、定义 SendGrid 配置属性 现在,为了与 SendGrid 服务交互并向用户发送电子邮件,我们需要配置 API Key 以验证 API 请求。我们还需要配置发件人姓名和电子邮件地址,它们应与我们在 SendGrid 账户中设置的发件人身份相匹配。
我们在项目的 application.yaml 文件中配置这些属性,并使用 @ConfigurationProperties 将这些值映射到 POJO,Service 层在与 SendGrid 交互时会引用配置的 POJO:
@Validated @ConfigurationProperties(prefix = "com.
1、简介 本文将带你了解如何在 Spring Boot 应用中使用 ProblemDetail 响应错误信息,无论我们处理的是 REST API 还是 Reactive Stream(响应式流),它都提供了一种向客户端传达错误的标准化方式。
2、为什么要关注 ProblemDetail? 使用 ProblemDetail 来标准化错误响应对任何 API 都至关重要。
它可以帮助客户理解和处理错误,提高 API 的可用性和可调试性。这将带来更好的开发体验和更强大的应用。
采用它还有助于提供更翔实的错误信息,这对维护我们的服务和排除故障至关重要。
3、传统的错误处理方式 在 ProblemDetail 之前,我们经常在 Spring Boot 中实现自定义 ExceptionHandler 和 ResponseEntity 来处理错误。我们会创建自定义的错误响应结构。这导致了不同 API 之间的不一致性。
这种方式不仅需要大量的模板代码。而且,缺乏表示错误的标准化方式,因此客户端很难统一解析和理解错误信息。
4、ProblemDetail 规范 ProblemDetail 规范是 RFC 7807 标准的一部分。它为错误响应定义了一致的结构,包括诸如类型(type)、标题(title)、状态(status)、详情(detail)和实例(instance)等字段。这种标准化提供了一个通用的错误信息格式,有助于 API 开发人员和使用者。
实现 ProblemDetail 可确保我们的错误响应具有可预测性并易于理解。这反过来提高了我们的 API 和其客户端之间的整体沟通效果。
5、在 Spring Boot 中实现 ProblemDetail 在 Spring Boot 中有多种方法可以实现 ProblemDetail。
5.1、通过配置属性启用 ProblemDetail 我们可以添加一个配置属性来启用它。对于 RESTful 服务,在 application.properties 中添加以下属性:
spring.mvc.problemdetails.enabled=true 此属性可使 ProblemDetail 自动用于基于 MVC(servlet 栈)的应用中的错误处理。
1、概览 本文将带你了解 Spring Boot @MockBeans 注解的用法。
2、示例项目 以一个简单的票据验证器(Ticket Validator)示例为例:
public class TicketValidator { private CustomerRepository customerRepository; private TicketRepository ticketRepository; public boolean validate(Long customerId, String code) { customerRepository.findById(customerId) .orElseThrow(() -> new RuntimeException("Customer not found")); ticketRepository.findByCode(code) .orElseThrow(() -> new RuntimeException("Ticket with given code not found")); return true; } } 如上,我们定义了 validate() 方法,用于检查数据库中是否存在给定数据。它依赖 CustomerRepository 和 TicketRepository。
现在,来看看如何使用 Spring 的 @MockBean 和 @MockBeans 注解创建测试和模拟依赖。
3、@MockBean 注解 Spring 框架提供了 @MockBean 注解,用于模拟依赖以进行测试。该注解允许我们定义特定 Bean 的模拟版本。新创建的模拟 Bean 将被添加到 Spring ApplicationContext 中。因此,如果已经存在相同类型的 Bean,它将被替换为模拟版本。
Spring Boot 中的 application.yaml / application.properties 配置文件用于定义应用运行时需要的配置属性。
Spring Boot 提供了强大的配置属性绑定功能,可以把配置文件中的属性绑定到 Java Bean,并且会根据 Java Bean 的字段类型对配置属性进行必要的转换。
绑定属性到 Bean 通过一个简单的示例来看看如何把配置文件中的配置属性绑定到 Bean,并且自动转换其类型。
本文使用的 Spring Boot 版本是 3.3.1。
创建 Spring Boot 项目 创建任意 Spring Boot 应用。
定义配置属性 在 src/main/resources 目录下创建 application.yaml 配置文件,并在其中定义如下自定义的配置属性:
app: # 数值 port: 8080 # 字符串 title: "Spring Boot 属性绑定测试" # Duration duration: 15s # DataSize data-size: 10MB # 集合 file-types: ["png", "jpeg"] 如上,在配置文件中定义了几个不同类型的配置属性。在本例中,这些配置属性的名称没有任何意义,随意取的。
定义配置 Bean 在 cn.springdoc.demo.prop 包下定义与配置文件中属性相对应的 Bean。
package cn.
1、概览 H2 是一个开源的 SQL 数据库,在 Java 中通常用于测试。它是一个内存数据库,不会将任何数据持久化到磁盘,因此速度非常快。
在与 Spring Boot 整合时,我们可能会遇到 “Schema not found” 异常,本文将带你了解出现此异常的原因,以及如何解决该异常。
2、理解异常的原因 H2 的默认 Schema 是 PUBLIC。如果我们映射的 JPA 实体类不使用 PUBLIC Schema,则必须确保在 H2 上创建了 Schema。当目标 Schema 不存在时,Spring Boot 会抛出异常 “Schema not found”。
模拟一下这个场景。在 Spring Boot 应用中创建以下实体类和 Repository。
@Entity @Table(name = "student", schema = "test") public class Student { @Id @Column(name = "student_id", length = 10) private String studentId; @Column(name = "name", length = 100) private String name; // 构造函数、Getter\Setter 方法 } 如上 @Table 注解指定了实体映射到 test Schema 下的 student 表的映射细节。
Spring Boot v3.3.2 正式发布。
🐞 Bug 修复 没有在 Spring Integration 6.2 中引入的 defaultTimeout 设置的配置属性 #41521 在 OnClassCondition.resolveOutcomesThreaded 中进行自动配置时出现 NPE,因为 firstHalf 为 null #41504 Spring 授权服务器现在将 multipleIssuersAllowed 默认为 false,并且不容易重新启用 #41355 ServiceConnection 无法与 @DataLdapTest 一起使用 #41325 PropertiesMigrationListener 错误地将属性报告为过时属性 #41252 @NestedConfigurationProperty 对 Record 不起作用 #41251 TestcontainersLifecycleBeanPostProcessor 无法与 Scope Bean 正常工作 #41238 如果 spring.config.import 无法解析,错误信息可能具有误导性 #41236 Docker desktop 更新后,构建镜像失败,提示 “Illegal char <:> at index 5: npipe:////” #41234 使用 Jetty 时,Filter、Listener 和 Servlet 未使用同一线程上下文 classloader 初始化 #41225 在 Webflux 中使用 DirtiesContext、随机端口和多个上下文的情况下,可能会导致多个上下文的行为异常 #41221 在原生镜像中使用 spring-boot-starter-activemq 时,org.
1、概览 本文将带你了解如何使用 Podman Desktop 对 Spring Boot 应用进行容器化。Podman 是一种容器化工具,它允许我们在不需要守护进程的情况下管理容器。
Podman Desktop 是一款具有图形用户界面(GUI)的桌面应用,用于使用 Podman 管理容器。
为了演示其用法,我们要创建一个简单的 Spring Boot 应用,构建容器镜像,并使用 Podman Desktop 运行容器。
2、安装 Podman Desktop 我们需要在本地计算机上 安装 Podman Desktop 才能开始使用。它适用于 Windows、macOS 和 Linux 操作系统。下载安装程序后,按照安装说明在机器上安装 Podman Desktop 即可。
以下是设置 Podman Desktop 的几个重要步骤:
机器上应已安装 Podman。如果没有安装,Podman Desktop 会提示并为我们安装。 Podman 准备就绪后,系统会提示我们启动 Podman 虚拟机。我们可以选择默认设置,也可以根据需要自定义设置。在运行容器之前,这是必须的。 此外,对于 Windows,需要启用/安装 WSL2(Windows Subsystem for Linux),然后才能运行 Podman。 在安装过程结束时,我们应该有一个正在运行的 Podman 虚拟机,并可以使用 Podman Desktop 进行管理。
可以在 “Dashboard”(仪表盘)部分看到:
3、创建 Spring Boot 应用 创建一个小型 Spring Boot 应用。该应用有一个 REST Controller,当我们访问 /hello 端点时,它返回一条 "Hello, World!