后端通用项目模板
基于 Spring Boot 的后端项目初始模板,整合常用框架和主流业务的示例代码
模板特点
主流框架 & 特性
- 基于 Spring Boot 3.5.x(原模板为 2.7.x,升级要点见文末版本差异)
- Spring MVC
- MyBatis + MyBatis Plus 数据访问(开启分页)
- Spring Boot 调试工具和项目处理器
- Spring AOP 切面编程
- Spring Scheduler 定时任务
- Spring 事务注解
数据存储
- MySQL 数据库
- Redis 内存数据库
- Elasticsearch 搜索引擎
- 腾讯云 COS 对象存储
工具类
- Easy Excel 表格处理
- Hutool 工具库
- Gson 解析库
- Apache Commons Lang3 工具类
- Lombok 注解
业务特性
- Spring Session Redis 分布式登录
- 全局请求响应拦截器(记录日志)
- 全局异常处理器
- 自定义错误码
- 封装通用响应类
- Swagger + Knife4j 接口文档
- 自定义权限注解 + 全局校验
- 全局跨域处理
- 长整数丢失精度解决
- 多环境配置
业务功能
- 提供示例 SQL(用户、帖子、帖子点赞、帖子收藏表)
- 用户登录、注册、注销、更新、检索、权限管理
- 帖子创建、删除、编辑、更新、数据库检索、ES 灵活检索
- 帖子点赞、取消点赞
- 帖子收藏、取消收藏、检索已收藏帖子
- 帖子全量同步 ES、增量同步 ES 定时任务
- 支持微信开放平台登录
- 支持微信公众号订阅、收发消息、设置菜单
- 支持分业务的文件上传
单元测试
- JUnit5 单元测试
- 示例单元测试类
架构设计
- 合理分层
快速上手
MySQL 数据库
1)修改 application.yml 的数据库配置为你自己的:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/my_db
username: root
password: root12342)执行 sql/create_table.sql 中的数据库语句,自动创建库表
3)启动项目,访问 http://localhost:8101/api/doc.html 即可打开接口文档,不需要写前端就能在线调试接口
Redis 分布式登录
1)修改 application.yml 的 Redis 配置为你自己的:
spring:
redis:
database: 1
host: localhost
port: 6379
timeout: 5000
password: 1234562)修改 application.yml 中的 session 存储方式:
spring:
session:
store-type: redis3)移除 MainApplication 类开头 @SpringBootApplication 注解内的 exclude 参数:
// 修改前:
@SpringBootApplication(exclude = {RedisAutoConfiguration.class})
// 修改后:
@SpringBootApplicationElasticsearch 搜索引擎
1)修改 application.yml 的 Elasticsearch 配置为你自己的:
spring:
elasticsearch:
uris: http://localhost:9200
username: root
password: 1234562)复制 sql/post_es_mapping.json 文件中的内容,通过调用 Elasticsearch 的接口或者 Kibana Dev Tools 来创建索引(相当于数据库建表)
PUT post_v1
{
参数见 sql/post_es_mapping.json 文件
}这步不会操作的话需要补充下 Elasticsearch 的知识,或者自行百度一下~
3)开启同步任务,将数据库的帖子同步到 Elasticsearch
找到 job 目录下的 FullSyncPostToEs 和 IncSyncPostToEs 文件,取消掉 @Component 注解的注释,再次执行程序即可触发同步:
使用教程
1、每个模块的简要概写
2、一些重点模块的讲解
2.1 全局项目配置
application.yml
数据库配置文件是每一个项目都要修改的,一般修改内容为:数据库库名,例如: my_db,用户名: xxxx 密码: xxxx。
Redis 在一伙伴匹配项目中用到,如有需要需要替换成自己的密码。并且在 Spring Boot 启动类中作出如下修改。
2.2 全局请求、鉴权拦截器
AuthInterceptor 和 LogInterceptor
先介绍下AuthInterceptor,权限校验机制,判断用户的role(角色)是否为管理员、用户、ban(封号)三种情况。
像创建用户这个方法就是只有管理员能够使用,用@AuthCheck自定义注解,然后写上使用该方法要有的权限即可。权限校验器因为是@Around环绕通知并且表明在有authCheck注解的方法周围执行如下逻辑。
@Around环绕通知在也就是在方法执行前后额外添加的逻辑。AOP功能的诠释,如果有不懂这段逻辑的可以去回顾下Spring的AOP功能, 面试 中经常会提及,能够回答出AOP的实际项目应用也是很不错的一个点。
接下来介绍一下 LogInterceptor
简要说明:请求日志拦截器,用于输出请求日志,@Around是环绕通知,然后用了切入点表达式,要拦截哪个包或者哪些包下面的哪个方法或者是全部方法。这段切入点表达式的功能就是对com.yupi.springbootinit.controller中所有方法进行拦截。也就是说控制层执行方法就会打印日志进行输出。有利用异常信息的捕获和后端调试debug。
2.3 通用响应类
BaseResponse、ResultUtils和 ErrorCode
下面是 BaseResponse 的介绍:
通用返回类,code 表示响应状态码,data 存放返回的数据,message :成功或者失败的额外信息。
下面是 ResultUtils 的介绍:
主要用于简化 BaseResponse 的操作,将成功,失败的一些通用情况进行的静态方法的封装,然后可以很方便的进行调用,比如调用 success 方法,响应状态码就是 0,然后会将data封装到 BaseResponse 的data属性,message为 "ok"。如果你的前端想要响应状态吗为 200,那么将这里的 0 改成 200就可以了,这边的message为固定消息 "ok"。可以再设置一个静态方法,进行方法重构,success形参为(T data,String message),然后可以动态定义成功的时候的返回消息。
下面是 ErrorCode 的介绍:
ErrorCode配合上面的ResultUtils使用,可以定义枚举类将常规的响应状态码和响应信息进行封装。比如: 无权限访问(40300),服务器内部异常(50000),你可以添加自定义的一些专属你自己项目的响应状态码,例如: API 项目 接口调用失败,可以是 INTERFACE_ERROR(50003,"接口调用失败")。
2.4 配置类
JsonConfig、Knife4jConfig、MyBatisPlusConfig、CorsConfig、CosClientConfig、WxOpenConfig
下面是 JsonConfig 的介绍:
@JsonComponent作用: 自定义序列化和反序列JSON数据,Spring Boot 默认使用 JackSon 进行序列化和反序列化。
怎么防止丢失? 用@Bean覆盖组件后,重写逻辑代码,将包装类 Long 和基础数据类型 long 转化成字符串序列化成字符串防止在序列化的时候丢失精度。
精度丢失场景 :id在数据库是 BigInteger 类型,雪花算法生成id大于17位,因此在序列化的时候会产生精度丢失。
下面是 Knife4jConfig 的介绍:
Knife4jConfig 用于后端接口在线测试的配置类。
图中@Profile用于指定在什么环境配置,和配置文件的 spring.profiles.active 是相互关联的。因此只在开发环境和测试环境中生效。
basePackage:用于指定要扫描 Controller 层的包, 如果你的控制层的包名有所不同,需要进行修改,Knife4j才能生效。
下面是 MyBatisPlusConfig 的介绍:
@MapperScan用于指定扫描的路径,如果你的项目的基础包名路径不同,需要修改为你自己的。
这边是用@Bean进行组件的注入,然后添加了分页插件。
MyBatisPlus还有很多插件,例如:乐观锁插件、多租户插件、动态表明插件、数据权限插件等等。可以去官网查看。
下面是 CorsConfig 的介绍:
CorsConfig 用来解决全局跨域配置问题,可以指定请求方法、是否允许发送 Cookie、放行哪些特定域名或 ip、允许哪些请求头。
下面是 CosClientConfig 的介绍:
直接将你的accessKey、secretKey、region、bucket进行替换即可,在application.yml中做替换,然后配合工具类即可使用对象云存储的功能。
下面是WxOpenConfig 的介绍:
在微信开放平台获取 appId、appSecret、等配置后,在 applicaiton.yml 中替换即可。
2.5 全局异常处理
BusinessException、GlobalExceptionHandler和ThrowUtils
下面是 BusinessException 的介绍:
code:错误码,message因为继承了父类RunTimeException,因此就有属性message。 结合ErrorCode使用 。
下面是GlobalExceptionHandler的介绍:
@RestControllerAdvice注解是@ControllerAdvie和@ResponseBody注解的组合,先捕获整个应用程序中抛出的异常,然后将异常处理方法的返回值将自动转换为HTTP响应的主体。
@ExceptionHandler注解用于指定什么异常需要被捕获。
下面是ThrowUtils的介绍:
一般用于请求参数的校验,如果请求参数为空,直接抛出业务异常,然后指明错误码ErroCode和message错误信息。
2.6 数据库和 ES 同步
IncSyncPostToEs和FullSyncPostToEs
下面是IncSyncPostToEs的介绍:
@Component 注解: 如果取消注解,就将这个定时任务加入到Spring 容器中,Spring Boot 启动类启动后将会开启这个定时任务。
@Scheduled: Spring Boot 的定时任务控制的注解,这里用于每分钟执行同步帖子的逻辑。
应用场景:
1.想要统计Top10的接口调用次数(API接口),在数据库量大后,每个用户去发送请求获取Top10的接口调用次数会造成数据库请求压力过大,此时可以写个定时任务,可以定时24小时,每天将Top10的接口调用次数同步到Redis存储,以接口名称和键以接口调用次数为值保存即可。实时性要求不太强的功能,可以采用定时任务。
2.某个API接口不用用户传参,而且大多数时间回复的调用结果都是相通的,那么就可以采取定时任务,将这些不用用户传参,并且调用结果都是相同的接口定时同步到Redis存储,相对于数据库的IO读取,Redis存储会大大提升这些接口的QPS,可以自己在简历上进行量化处理。
2.7 工具类
NetUtils、SpringContextUtils、SqlUtils
下面是 NetUtils 的介绍:
主要用于获取客户端的 IP 地址
下面是 SpringContextUtils 的介绍:
用于通过名称、类型、名称和类型获取 Spring 上下文的容器。
下面是 SqlUtils 的介绍:
主要用于检查 SQL 注入问题
版本差异(Spring Boot 2.7.x → 3.5.x)
| 特性 | 旧版(2.7.x 模板) | 当前(3.5.x) |
|---|---|---|
| Spring Boot | 2.7.x | 3.5.x(JDK 17-24,jakarta) |
| Knife4j | 3.x(springfox 系) | 4.x(openapi3-jakarta 系) |
| MyBatis-Plus | 3.5.x(兼容 2.7) | 3.5.12(mybatis-plus-spring-boot3-starter) |
| 微信 SDK | weixin-java-mp 4.x | 4.x 不变(支持 jakarta 版本) |
| Sa-Token/Shiro | javax | 需用 jakarta 版(Sa-Token 1.38+) |
| ES 客户端 | spring-boot-starter-data-elasticsearch | 不变;注意 ES 版本与客户端版本匹配 |
模板的分层结构(controller/service/mapper/config)、拦截器、全局异常、统一返回等设计完全复用;升级重点是 Knife4j 换 4.x、MyBatis-Plus 换 boot3 starter、微信 SDK 换 jakarta 版。