2021-12-25更新
- 本项目已上传中央仓库,欢迎使用
1 | xml复制代码<dependency> |
- 快速生成项目:执行如下命令,可快速生成包含本项目功能的springboot项目
1 | shell复制代码mvn archetype:generate -DarchetypeGroupId=io.github.chenxuancode -DarchetypeArtifactId=archetype -DarchetypeVersion=1.0.0-Release -DgroupId=io.github.chenxuancode -DartifactId=demo -Dport=8888 |
Tip:
DgroupId修改为你的groupId,DartifactId修改为你项目的artifactId
命令控制台会确认你项目的groupId、artifactId等信息,如无需修改回车确认即可
- 本项目代码已更新至github.com/chenxuancod…
last: 欢迎大家反馈建议!!! 码字不易,各位小可爱给个点赞关注star1
2
3
4
5
6
7
8
9
10
11
12
-------------------------------------------------------------------------分割
**正文**
在成熟的项目开发中,都会由基础包提供一些项目通用性的功能组件,避免每个项目重复造轮子。本项目将springboot项目开发中常用的基础功能进行封装,目前本包具备**统一依赖管理**、**异常处理**、**响应报文包装**、**统一日志管理**、**敏感数据加解密**等功能。支持可插拔方式,只要引入依赖便具备上述功能。
下面讲讲如何实现
统一依赖管理
将一些常用的依赖,统一梳理到基础包中,可以方便后续对组件进行管理(升级或漏洞修复之类),基础包中的组件依赖原则是稳定以及最少依赖。目前base包括以下组件,基本满足springboot项目开发的基本功能。各项目基础包的依赖由base统一管理,只需要引入base模块即可,特性包由各项目自己引入。
目前的基础包已经集成了mybatis-plus swagger等常用的基础组件
组件名称 | 版本 |
---|---|
spring-boot-starter-validation | 2.3.12.RELEASE |
spring-boot-starter-web | 2.3.12.RELEASE |
spring-boot-starter-test | 2.3.12.RELEASE |
spring-boot-starter-aop | 2.3.12.RELEASE |
mysql-connector-java | 8.0.16 |
mybatis-plus | 3.4.0 |
springfox-swagger2 | 2.8.0 |
springfox-swagger-ui | 2.8.0 |
swagger-bootstrap-ui | 1.8.5 |
lombok | 1.18.20 |
hutool-all | 5.7.14 |
异常处理
定义了统一全局异常处理器,鼓励不在业务代码中进行异常捕获, 将 dao、service、controller 层的所有异常全部抛出到上层. 减少try-catch对业务代码的侵入性
如果需要返回接口的指定错误提示信息,可以直接抛出自定义异常AiException
1 | java复制代码throw new ApiException("两次密码输入不一致"); |
实现原理
使用@RestControllerAdvice
开启全局异常的捕获,自定义一个方法使用ExceptionHandler
注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。
1 | java复制代码@Slf4j |
其它未显式抛出的异常会自动被外层异常处理器识别为未知错误并返回前端
日志处理
在springboot项目中,通常使用logback组件进行日志管理。那么如果每一个服务自己写一份logback配置文件,势必会导致日志格式、日志路径五花八门,不好管理,所以日志处理交由基础包统一处理。
通常日志处理需要思考的几个点包括:日志如何打印、日志如何拆分管理、日志如何收集
出入参日志打印
在Controller方法上使用@WebLog便可实现请求响应报文的打印
1 | java复制代码@PostMapping("/register") |
实现原理
定义日志切面LogAspect
,
1 | java复制代码public class LogAspect { |
WebLog
注解
1 | java复制代码@Retention(RetentionPolicy.RUNTIME) |
日志拆分保存
日志拆分保存通过logback进行配置,当前日志进行错误日志与普通日志的拆分,每种文件类型再按天进行拆分,当天超过200M的日志文件再以文件名中编号递增的形式进行拆分,具体规则如下${LOG_ERROR_HOME}/${springAppName}-%d{yyyy-MM-dd}.%i.log ${LOG_INFO_HOME}/${springAppName}-%d{yyyy-MM-dd}.%i.log
|
使用AsyncAppender
异步输出的方式输出日志,完整的logback日志请查看:
链路追踪
目前链路追踪通过MDC实现,MDC是Slf4J类日志系统中实现分布式多线程日志数据传递的重要工具可利用MDC将一些运行时的上下文数据打印出来。关于MDC的介绍可以看看这篇juejin.cn/post/690122…
实现原理
通过拦截器对请求进行拦截,生成traceId并通过MDC put接口设置到THreadLocalMap中
1 | java复制代码public class LogInterceptor implements HandlerInterceptor { |
在logback-spring.xml中增加%X{traceId}
1 | xml复制代码<property name="PATTERN" value="%red(%d{yyyy-MM-dd HH:mm:ss.SSS}) %X{traceId} %yellow(%-5level) %highlight([%t]) %boldMagenta([%C]).%green(%method[%L]): %m%n"/> |
响应报文自动封装
通常接口都需要按照一定的结构返回,包括服务处理结果编码、编码对应的文本信息、返回值等,可以通过 @RestControllerAdvice
对Controller进行增强实现响应报文的自动封装
1 | java复制代码@RestControllerAdvice("com.sleeper") |
对于不想自动封装结果的接口,使用注解 @NotResponseWrap
在方法上标记即可
敏感数据加解密
有时候,在开发过程中需要对某一些数据如手机号、身份证号等数据在保存到数据库的时候进行加密处理,防止数据泄露。本基础包提供了@SensitiveData
(作用于CLASS) @SensitiveField
(作用于FEILD,以实现加解密操作,只需在数据实体对象上加上 @SensitiveData
注解,在敏感字段上加上@SensitiveField
便可实现敏感数据加解密操作。
1 | java复制代码@Data |
实现原理
重写mybatis拦截器 ResultSetHandler.handleResultSets
ParameterHandler.setParameters
方法,在设置请求参数时识别注解并将字段进行AES加密,在获取结果集时识别注解并将字段进行AES解密.详情请看: github.com/chenxuancod…
优雅停机
没有优雅停机,服务器此时直接直接关闭(kill -9),那么就会导致当前正在容器内运行的业务直接失败,在某些特殊的场景下产生脏数据。开启优雅停机后,在web容器关闭时,web服务器将不再接收任何请求,并将等待活动请求完成的缓冲器。
实现原理
基础包使用的Spring Boot 2.3版本内置此功能,不需要再自行扩展容器线程池来处理,Jetty, Reactor Netty, Tomcat和 Undertow 以及反应式和基于 Servlet 的 web 应用程序都支持优雅停机功能,只需要配置server.shutdown=graceful
.
本基础包默认开启优雅停机功能,通过SPI
机制在服务中进行配置注入,并结合后续部署脚本以服务优雅停机的统一管理
1 | scss复制代码@Configuration |
本文转载自: 掘金