news 2026/8/26 15:32:48

《SpringBoot 3:入门与应用实战》第 6 章 Spring Boot 最佳实践 阅读笔记 12

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
《SpringBoot 3:入门与应用实战》第 6 章 Spring Boot 最佳实践 阅读笔记 12

《SpringBoot 3:入门与应用实战》第 6 章 Spring Boot 最佳实践 阅读笔记 12

6.7 启动异常分析

我们在开发应用的过程中几乎无法避免遇到各种错误和异常,小到端口冲突,大到内存泄漏等。

6.7.1 FailureAnalyzer

正常情况下,当应用运行过程中出现异常时,由抛出方逐层向上传递,直至由 catch 块捕获,或者在没有捕获时最终抛出并打印,Spring Boot 提供的异常分析机制相当于从 catch 层切入,它提供了一个核心组件 FailureAnalyzer 和一组实现,以拦截应用启动过程中抛出的异常并尝试处理。

FailureAnalyzer 本身是一个接口,它来自 Spring Boot 1.4,由于该接口中只有一个方法,因此在 Spring Boot 2.0 中被声明为函数式接口。

接口的设计非常简洁,参数是 Throwable 对象,经过 analyze 方法处理后转换为一个 FailureAnalysis 对象,FailureAnalysis 的结构其实就是 Throwable 的包装,额外添加了可以自行填写内容的 description 和 action 属性,以便每个异常分析器 (FailureAnalyzer) 描述自己负责的异常,以及出现该异常时的检查和修复建议动作。

Spring Boot 内置了很多 FailureAnalyzer 的实现,它们被定义在 META-INF/spring.factories 文件中。当应用启动时,Spring Boot 会加载这个文件并将声明的所有 FailureAnalyzer 注册到 IOC 容器中,以备后续启动过程中出现异常时做出反应。

以端口号被占用的异常为例,可以在 spring.factories 文件的 FailureAnalyzer 配置项中找到一个实现类 PortInUseFailureAnalyzer,它可以识别和分析端口号被占用的问题。经查看它的源码可以发现,它处理异常的方式非常简单,就是把被占用的端口号取出并封装为异常报告信息,生成 FailureAnalysis 对象。这就意味着只要在启动过程中抛出了 PortInUseException 异常,PortInUseFailureAnalyzer 就可以将其捕获并封装异常分析信息。

6.7.2 重写内置的异常分析

Spring Boot 提供的内置异常分析组件很多,开发人员通过读取异常分析信息可以相对简单地了解启动异常和定位,但如果交给对日志不很了解的运维人员,可能就不是很友好。为了解决该问题,可以针对内置组件中不易理解和获取错误定位的异常进行重写,通过重写异常分析信息提供更易理解的错误提示和修复指导。

以 6.7 节的端口号被占用为例,如果我们需要重写端口被占用时的异常提示信息,可以编写一个新的类ChinesePortInUseFailureAnalyzer(基于中文的端口号被占用分析器),使其继承 FailureAnalyzer 的抽象父类AbstractFailureAnalyzer,并指定捕获的异常类型为 PortInUseException,即可在 analyze 方法中获取该异常并自行封装 FailureAnalysis 信息。

packagecom.yangjunbo.springboot.practice.examplee;importorg.springframework.boot.diagnostics.AbstractFailureAnalyzer;importorg.springframework.boot.diagnostics.FailureAnalysis;importorg.springframework.boot.web.server.PortInUseException;publicclassChinesePortInUseFailureAnalyzerextendsAbstractFailureAnalyzer<PortInUseException>{@OverrideprotectedFailureAnalysisanalyze(ThrowablerootFailure,PortInUseExceptioncause){returnnewFailureAnalysis("当前端口"+cause.getPort()+"被占用!","检查"+cause.getPort()+"为什么被占用,并停止占用的程序。",rootFailure);}}

要想让自己编写的异常分析器生效,需要遵循 Spring Boot 的规则,将 hinesePortIn UseFailureAnalyzer 配置到 spring.factories 文件的 FailureAnalyzer 配置项中,所以接下来在 resources/META-INF 目录下创建 spring.factories 文件。

org.springframework.boot.diagnostics.FailureAnalyzer=\ com.yangjunbo.springboot.practice.examplee.ChinesePortInUseFailureAnalyzer

如此编写完毕后,下面重启应用测试效果。和预期一致,工程启动失败,但是控制台中打印的异常分析信息变为编写的中文内容,说明自行编写的异常分析器可以覆盖 Spring Boot 内置的组件。

6.7.3 自定义异常分析

随着应用的不断开发,在应用启动阶段可能会添加新的扩展逻辑,伴随这些扩展逻辑的添加,可能会有一些校验逻辑附加到启动阶段。为了能在校验失败时提供更易读的错误报告和修改提示,可以自定义校验的异常,以及为这些异常制定异常分析规则。

使用一个比较简单的场景作为示例。自定义的异常场景是:当应用启动的端口号被设置为 5 位数时,抛出异常终止程序运行。

首先定义一个新的运行时异常类 IllegalPortException,使其继承 Runtime Exception 并在内部声明一个 int 类型的变量,用于接收不合法的端口号。

packagecom.yangjunbo.springboot.practice.examplef;/** * 不合法的端口异常 */publicclassIllegalPortExceptionextendsRuntimeException{privateintport;publicIllegalPortException(intport){this.port=port;}publicintgetPort(){returnport;}}

为了能在应用启动阶段将该异常抛出,可以借助 6.5.4 节中学习的 CommandLineRunner 接口来触发,声明一个 IllegalPortChecker 类,实现CommandLineRunner 接口并标注 @Component 注解,随后实现端口检测逻辑。注意,@Value 注解中使用的占位符考虑了未声明 server.port的情况。

packagecom.yangjunbo.springboot.practice.examplef;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.boot.CommandLineRunner;importorg.springframework.stereotype.Component;@ComponentpublicclassIllegalPortCheckerimplementsCommandLineRunner{@Value("${server.port:8080}")privateintport;@Overridepublicvoidrun(String...args){if(port>10000){thrownewIllegalPortException(port);}}}

接下来是与 IllegalPortException 异常对应的异常分析器,仿照 Spring Boot 的编写风格,可以快速编写出相对应的 IllegalPortFailureAnalyzer。

packagecom.yangjunbo.springboot.practice.examplef;importorg.springframework.boot.diagnostics.AbstractFailureAnalyzer;importorg.springframework.boot.diagnostics.FailureAnalysis;publicclassIllegalPortFailureAnalyzerextendsAbstractFailureAnalyzer<IllegalPortException>{@OverrideprotectedFailureAnalysisanalyze(ThrowablerootFailure,IllegalPortExceptioncause){returnnewFailureAnalysis("检测到不合法的端口:"+cause.getPort(),"请使用10000以内的端口号",cause);}}

最后将 IllegalPortFailureAnalyzer 配置到 spring.factories 文件中,即可完成全部工作。

org.springframework.boot.diagnostics.FailureAnalyzer=\ com.yangjunbo.springboot.practice.examplee.ChinesePortInUseFailureAnalyzer,\ com.yangjunbo.springboot.practice.examplef.IllegalPortFailureAnalyzer

这个 \ 符号在 Java 的配置文件中叫做续行符(Line Continuation Character)。
它的作用非常简单:告诉解析器,当前行还没有结束,下一行是当前行的延续。

全部编码工作完成后,修改 application-dev.properties 文件中 server.port 的值为 18080,并重新运行工程,这次虽然不会提示端口冲突,但由于使用的端口号 “不合法”​,导致 IllegalPortException 异常被抛出,最终控制台会打印如下错误报告,证明自定义的异常报告组件已经生效。

6.8 小结

Spring Boot 之所以强大,其可配置性和高扩展性必定占有一席之地。通过使用 properties 或 YML 格式的文件声明配置,并辅以 Profile 特性,可以轻松地定义多套不同运行环境下的配置;结合属性绑定功能,将配置文件中的配置属性映射到特定的属性模型类中,可以方便地管理和使用这些配置属性。

Spring Boot 的日志体系天然集成在官方的场景启动器中,默认使用 Slf4j + Logback 的日志门面+实现组合,借助 Spring Boot 的整合能力,可以直接在全局配置文件中自定义日志的输出格式、日志载体、日志级别等。

Spring Boot 中可以切入的扩展点非常多,从启动容器前到容器初始化阶段,再到应用启动完成后的一系列过程都有非常多的切入点。

Spring Boot 快速搭建工程的秘籍之一是场景启动器,场景启动器中包含一个应用开发场景中所需的全部依赖和相关的配置,自行制作场景启动器时也需要将这些因素全部考虑进去。

对于应用启动过程中出现异常的问题,Spring Boot 通过启动异常分析机制将异常捕获,并转换为可读的错误提示和修复建议,帮助开发者排查问题;针对应用中扩展的功能,也可以提前考虑潜在的问题,并编写相应的自定义异常和分析器,以提供更友好的提示信息。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/26 15:32:26

Snap.Hutao 胡桃工具箱:5分钟查完抽卡保底与培养材料缺口

Snap.Hutao 胡桃工具箱&#xff1a;5分钟查完抽卡保底与培养材料缺口 【免费下载链接】Snap.Hutao 实用的开源多功能原神工具箱 &#x1f9f0; / Multifunctional Open-Source Genshin Impact Toolkit &#x1f9f0; 项目地址: https://gitcode.com/GitHub_Trending/sn/Snap.…

作者头像 李华
网站建设 2026/8/26 15:31:57

K8S集群安装部署

本次安装使用kubeadmcontainerd运行时方式进行安装&#xff0c;三台master,三台node,两台主机安装haproxy&#xff0c;所有系统均为ubuntu24.04 主机规划 IP地址hostname 安装组件192.168.10.31k8s-master-01kube-apiserver/kube-controller-manager/kube-scheduler/etcd192.…

作者头像 李华
网站建设 2026/8/26 15:31:07

从安装到出片:ComfyUI-LTXVideo 用 LTX-2 生成 AI 视频的实操教程

从安装到出片&#xff1a;ComfyUI-LTXVideo 用 LTX-2 生成 AI 视频的实操教程 【免费下载链接】ComfyUI-LTXVideo LTX-Video Support for ComfyUI 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-LTXVideo ComfyUI-LTXVideo 是为 ComfyUI 制作的 LTX-2 视频…

作者头像 李华
网站建设 2026/8/26 15:27:12

2026-08-24-rag三件套

RAG 检索优化实战&#xff1a;混合检索 RRF Rerank 三件套&#xff08;附代码与参数表&#xff09; 前言 先说个我自己踩过的事&#xff1a;几百页文档灌进知识库&#xff0c;问它「XX 设备的故障码 E-123 怎么处理」&#xff0c;AI 张嘴就编了个像模像样的答案。我翻回文档一…

作者头像 李华
网站建设 2026/8/26 15:26:25

数据分析其实没那么难:吃透这8张图,搞定90%的分析问题

做数据分析久了&#xff0c;我越来越觉得&#xff0c;很多人不是不会分析&#xff0c;而是一开始就把这件事想复杂了。一提到数据分析&#xff0c;就容易联想到统计模型、算法、SQL、Python&#xff0c;好像工具越多&#xff0c;分析能力就越强。但真正到了企业里&#xff0c;大…

作者头像 李华