Java 后端开发规范
制定背景
提供一套可复用的标准化开发规范,适用于 Spring Boot 企业级应用开发。
核心原则
- OpenAPI 规范驱动 - 前后端通过接口规范对齐,零沟通成本
- 类型安全优先 - TypeScript 强制类型校验,早发现早修复
- 约定大于配置 - 统一代码风格和目录结构,降低认知负担
- 自动化优先 - 能自动化的绝不手动(代码生成、部署、测试)
- 三层架构分离 - Controller、Service、Mapper 职责清晰
一、技术栈规范
后端技术栈
| 组件 |
技术选型 |
版本 |
说明 |
| 框架 |
Spring Boot |
3.2+ |
基于 Java 17 |
| 持久层 |
MyBatis-Plus |
3.5+ |
简化 CRUD |
| 对象映射 |
MapStruct |
1.5+ |
VO/Entity 转换 |
| 数据库连接池 |
Alibaba Druid |
1.2+ |
数据库连接池 + 监控 |
| 安全 |
Spring Security + JWT |
- |
无状态认证 |
| API 文档 |
Knife4j (SpringDoc) |
4.x |
OpenAPI 3.0 |
| 数据库 |
MySQL |
8.0+ |
关系型数据库 |
| 迁移 |
Flyway |
- |
版本化数据库变更 |
| 校验 |
Hibernate Validator |
- |
JSR-303 参数校验 |
| 缓存 |
Redis + Spring Data Redis |
- |
缓存、会话存储 |
| 日志 |
Logback |
- |
结构化日志 |
| JSON |
FastJSON |
2.x |
JSON 序列化 |
| 工具类 |
Hutool |
5.x |
常用工具集合 |
| 文件存储 |
阿里云 OSS |
- |
对象存储 |
二、项目结构规范
后端目录结构
主要模块包括 common(公共模块)、controller(控制器层)、service(服务层)、mapper(数据访问层)、entity(实体类)、dto(数据传输对象)、enums(枚举类)。资源配置包括 application 配置文件、Flyway 迁移脚本、日志配置、MyBatis XML。
三、三层架构规范
各层职责
| 层级 |
职责 |
数据接收 |
数据返回 |
| Controller |
接收请求、参数校验、调用 Service、返回响应 |
DTO/Request |
VO/Response |
| Service |
处理业务逻辑、事务控制 |
DTO/Entity |
Entity |
| Mapper |
数据库 CRUD 操作 |
Entity/条件 |
Entity |
核心规范
- Service/Mapper 层必须使用实体类 - Service↔Mapper 之间只用 Entity,禁止 DTO/VO 转换
- 转换只在 Controller 层发生 - Entity ↔ VO 转换统一在 Controller 层处理
- Service 继承 IService - 所有 Service 接口继承 MyBatis-Plus 的 IService
- 查询接口默认分页 - 所有返回列表的查询接口,默认进行分页处理
查询方式选择
| 场景 |
推荐方式 |
| 单表按 ID 查询 |
通用方法 getById(id) |
| 单表条件查询 |
QueryWrapper list(wrapper) / getOne(wrapper) |
| 单表分页查询 |
QueryWrapper + Page page(new Page<>(p, s), wrapper) |
| 单表统计 |
QueryWrapper count(wrapper) |
| 两表联查 |
自定义 SQL mapper.selectWithXxx() |
| 三表及以上 |
自定义 SQL |
| 聚合统计 |
自定义 SQL |
| 动态复杂条件 |
自定义 SQL(XML) |
消除魔法值规范
核心原则:禁止在代码中使用魔法值,所有状态、类型、常量必须使用枚举定义
| 场景 |
规范 |
| 状态字段 |
使用枚举定义(如 CommonStatusEnum) |
| 类型字段 |
使用枚举定义(如 UserTypeEnum) |
| 常量值 |
使用常量类或接口定义 |
| 错误码 |
使用枚举定义(如 ErrorCode) |
枚举设计规范:
- 枚举类统一存放在
enums 包下
- 枚举包含
code 和 desc 字段,便于前端展示
- 提供
getCode()、getDesc()、valueOfCode() 方法
- 数据库存储
code,代码中使用枚举
四、ORM 实体类规范
1. 表名命名规范
所有数据库表必须添加业务模块前缀,格式为 t_{模块}_{表名}:
| 模块分类 |
前缀 |
示例 |
| 用户模块 |
t_user_ |
t_user, t_user_role |
| 系统模块 |
t_sys_ |
t_sys_config, t_sys_log |
| 业务模块 |
t_biz_ |
t_biz_order, t_biz_product |
| 权限模块 |
t_auth_ |
t_auth_role, t_auth_menu |
2. 表名与实体类名对应规范
表名与实体类名必须保持一致,仅允许下划线与驼峰的区别:
| 表名(下划线命名) |
实体类名(驼峰命名) |
t_auth_role |
AuthRole |
t_user_role |
UserRole |
t_sys_config |
SysConfig |
3. 不使用外键约束规范
- 数据库表之间不使用 FOREIGN KEY 外键约束
- 表与表之间的关联关系通过代码逻辑控制
- 关联查询通过
JOIN 或应用层组装实现
4. 多对多关系中间表命名规范
核心原则:中间表名必须清晰表达两个关联实体的关系
- 标准命名格式:
t_{实体 A}_{实体 B}
- 按字母顺序或业务逻辑顺序排列
- 不使用
relation、rel、link 等冗余词
- 实体类名直接使用两个实体名的组合(如
ParentStudent)
5. 基础实体类
所有实体类继承 BaseEntity,包含公共字段:
| 字段 |
类型 |
说明 |
自动填充 |
| id |
Long |
主键 ID(自增) |
数据库自增 |
| createBy |
String |
创建人 |
插入时 |
| createTime |
LocalDateTime |
创建时间 |
插入时 |
| updateBy |
String |
更新人 |
更新时 |
| updateTime |
LocalDateTime |
更新时间 |
更新时 |
| deleted |
Integer |
逻辑删除标识 |
- |
6. 审计字段规范
所有数据库表必须包含审计字段,用于追踪数据变更历史:
| 审计字段 |
类型 |
说明 |
必填 |
| create_by |
VARCHAR(50) |
创建人账号 |
是 |
| create_time |
DATETIME |
创建时间 |
是 |
| update_by |
VARCHAR(50) |
更新人账号 |
是 |
| update_time |
DATETIME |
更新时间 |
是 |
| deleted |
TINYINT |
逻辑删除标识(0-未删除,1-已删除) |
是 |
规范要求:
- 审计字段通过 MyBatis-Plus
FieldFill 自动填充
- 禁止在业务代码中手动设置审计字段
- 生产环境审计字段不得为空
五、日志规范
1. 日志语言规范(重要)
所有日志打印内容必须使用中文
| 场景 |
推荐格式 |
示例 |
| 操作开始 |
"开始{操作},{关键参数}" |
开始创建用户,用户名:zhangsan |
| 操作成功 |
"{操作}成功,{关键结果}" |
用户创建成功,ID: 123 |
| 操作失败 |
"{操作}失败,{关键参数}" |
用户删除失败,ID: 123 |
| 查询操作 |
"{动作}{对象},{关键参数}" |
查询用户,ID: 123 |
| 状态检查 |
"{对象}不存在/已存在,{关键参数}" |
用户不存在,ID: 123 |
| 异常日志 |
"{操作}异常,{关键参数}" + e |
创建用户异常,ID: 123 + e |
2. 日志级别使用场景
| 级别 |
使用场景 |
| ERROR |
系统异常,需要人工介入(数据库连接失败、第三方服务调用失败) |
| WARN |
业务异常,可预期的错误(参数校验失败、资源不存在) |
| INFO |
重要的业务操作记录(用户登录、订单创建、支付完成) |
| DEBUG |
调试信息,开发时使用(方法入参、SQL 执行结果) |
3. TraceId 链路追踪规范
- 使用
MDC(Mapped Diagnostic Context)实现 TraceId 链路追踪
- 通过 AOP 切面在请求入口自动生成 TraceId 并放入 MDC
- 请求结束时清除 MDC,防止内存泄漏
- 日志格式包含
[%X{traceId}] 实现全链路追踪
4. 环境差异化日志配置
| 环境 |
日志策略 |
| 开发/测试环境 |
全量记录(DEBUG 级别),包含所有业务日志、SQL 日志、调试信息 |
| 生产环境 |
精简记录(INFO/WARN 级别),仅记录:请求日志、错误堆栈、错误 SQL、关键业务操作 |
5. AOP 日志实现规范
- 使用
@Aspect 定义日志切面,拦截 Controller 层所有方法
- 请求日志包含:TraceId、请求方法、请求路径、IP、耗时
- 异常日志包含:TraceId、异常类型、异常消息、堆栈信息
- 生产环境关闭 DEBUG 日志,避免性能损耗和日志膨胀
六、统一响应格式
1. 响应类定义
Result 统一响应类包含 code(状态码)、message(消息)、data(数据)、timestamp(时间戳)字段。
2. 错误码枚举
| 错误码 |
说明 |
| 200 |
成功 |
| 400 |
请求参数错误 |
| 401 |
未登录或 Token 已过期 |
| 403 |
没有访问权限 |
| 404 |
资源不存在 |
| 500 |
系统内部错误 |
3. 全局异常处理器
- 使用
@RestControllerAdvice 定义全局异常处理器
- 业务异常返回对应错误码
- 系统异常统一返回 500
七、多环境配置规范
1. 配置文件目录结构
配置文件包括 application.yml(主配置)、application-dev.yml(开发环境)、application-test.yml(测试环境)、application-prod.yml(生产环境)。
2. 环境配置对比
| 配置项 |
开发环境 (dev) |
测试环境 (test) |
生产环境 (prod) |
| 数据库 |
本地 MySQL |
测试服务器 |
生产服务器 |
| SQL 日志 |
开启 |
开启 |
关闭 |
| Swagger |
开启 |
开启 |
关闭 |
| Flyway Clean |
允许 |
禁止 |
禁止 |
| JWT 密钥 |
默认值 |
默认值 |
必须环境变量 |
| Redis 连接池 |
默认 |
默认 |
优化配置 |
3. 环境切换方式
- 方式一:环境变量
export SPRING_PROFILES_ACTIVE=prod
- 方式二:命令行参数
java -jar project.jar --spring.profiles.active=prod
八、工具类使用规范
1. 工具函数存放位置
| 场景 |
存放位置 |
| 多个地方调用(≥2 处) |
统一工具类(如 CommonUtil) |
| 仅在一个地方调用 |
Service 层内部私有方法 |
| 业务无关的通用工具 |
独立工具类(如 DateUtil, FileUtil) |
2. 工具类设计原则
- 私有构造 - 防止实例化
- 静态方法 - 所有方法都是
static 的
- 无状态 - 工具类不应持有状态
- 线程安全 - 工具方法必须是线程安全的
- 充分注释 - 每个方法都要有 JavaDoc 注释
3. 工具类命名规范
| 类型 |
命名格式 |
示例 |
| 通用工具类 |
XxxUtil |
CommonUtil, DateUtil, FileUtil |
| 业务工具类 |
XxxHelper |
UserHelper, OrderHelper |
| 转换工具类 |
XxxConverter |
EntityConverter, DtoConverter |
九、MapStruct 对象映射规范
1. Maven 依赖
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.5.5.Final</version>
</dependency>
2. 使用规范
- 定义 Converter 接口,使用
@Mapper 注解
- 接口方法用于 Entity ↔ VO 之间的转换
- 在 Controller 层调用 Converter 进行对象转换
- 禁止在 Service 层和 Mapper 层进行 DTO/VO 转换
3. 命名规范
| 类型 |
命名格式 |
示例 |
| 对象映射接口 |
XxxConverter 或 XxxMapStruct |
UserConverter, OrderConverter |
十、Hutool 工具类使用
常用工具方法
- 生成 UUID(不带横杠):
IdUtil.fastSimpleUUID()
- 密码加密(BCrypt):
SecureUtil.bcrypt(password)
- 密码校验:
SecureUtil.bcryptVerify(password, encrypted)
- 手机号验证:
Validator.isMatchRegex("^1[3-9]\\d{9}$", phone)
- 手机号脱敏:
DesensitizedUtil.mobilePhone(phone)
十、Swagger/Knife4j 配置规范
1. 接口文档访问
- Knife4j UI:
http://localhost:8080/doc.html
- OpenAPI JSON:
http://localhost:8080/v3/api-docs
2. Controller 层注解
- 使用
@Tag 注解标注控制器
- 使用
@Operation 注解标注接口
- 使用
@Schema 注解标注 DTO 字段
十一、工具函数使用规范
核心原则:工具函数必须集中管理,禁止在 Controller 层直接编写工具方法
工具函数存放位置
| 场景 |
存放位置 |
| 多个地方调用(≥2 处) |
统一工具类(如 CommonUtil) |
| 仅在一个地方调用 |
Service 层内部私有方法 |
| 业务无关的通用工具 |
独立工具类(如 DateUtil, FileUtil) |
工具类命名规范
| 类型 |
命名格式 |
示例 |
| 通用工具类 |
XxxUtil |
CommonUtil, DateUtil, FileUtil |
| 业务工具类 |
XxxHelper |
UserHelper, OrderHelper |
| 转换工具类 |
XxxConverter |
EntityConverter, DtoConverter |
十二、限流规范
技术选型
| 方案 |
适用场景 |
| Redis 滑动窗口 |
推荐:全局限流 |
| 自定义注解 + AOP |
推荐:特殊接口限流 |
常见限流场景建议值
| 接口类型 |
时间窗口 |
最大请求数 |
说明 |
| 登录接口 |
60 秒 |
10 |
防止暴力破解 |
| 验证码/短信 |
60 秒 |
3-5 |
防止短信轰炸 |
| 文件上传 |
60 秒 |
30 |
防止资源滥用 |
| 普通业务接口 |
60 秒 |
100-1000 |
根据业务调整 |
| 导出接口 |
60 秒 |
5-10 |
防止服务器过载 |
十三、FastJSON 配置规范
JSON 工具类
toJson(Object) - 对象转 JSON 字符串
parseObject(String, Class) - JSON 字符串转对象
parseArray(String, Class) - JSON 字符串转列表
十四、阿里云 OSS 文件上传规范
OSS 配置
配置项包括 endpoint、access-key-id、access-key-secret、bucket-name、url-prefix,均通过环境变量注入。
文件命名规范
- 使用日期目录:
yyyy/MM/dd/
- 使用 UUID 文件名,避免重名冲突
附录:快速参考
表名命名规范
t_user_* - 用户模块
t_sys_* - 系统模块
t_biz_* - 业务模块
t_auth_* - 权限模块
Redis Key 命名规范
auth:token:{token} - 用户 Token
user:info:{userId} - 用户信息缓存
dict:{type} - 数据字典
lock:{resource}:{id} - 分布式锁
rate_limit:{key} - 限流计数器
核心配置速查
| 配置项 |
环境变量 |
| 活跃环境 |
SPRING_PROFILES_ACTIVE |
| 数据库地址 |
DB_HOST |
| 数据库密码 |
DB_PASSWORD |
| Redis 地址 |
REDIS_HOST |
| Redis 密码 |
REDIS_PASSWORD |
| JWT 密钥 |
JWT_SECRET |
| OSS AccessKey |
OSS_ACCESS_KEY_ID |
| OSS Secret |
OSS_ACCESS_KEY_SECRET |