# Java 后端开发规范 ## 制定背景 提供一套可复用的标准化开发规范,适用于 Spring Boot 企业级应用开发。 ## 核心原则 1. **OpenAPI 规范驱动** - 前后端通过接口规范对齐,零沟通成本 2. **类型安全优先** - TypeScript 强制类型校验,早发现早修复 3. **约定大于配置** - 统一代码风格和目录结构,降低认知负担 4. **自动化优先** - 能自动化的绝不手动(代码生成、部署、测试) 5. **三层架构分离** - 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 | ### 核心规范 1. **Service/Mapper 层必须使用实体类** - Service↔Mapper 之间只用 Entity,禁止 DTO/VO 转换 2. **转换只在 Controller 层发生** - Entity ↔ VO 转换统一在 Controller 层处理 3. **Service 继承 IService** - 所有 Service 接口继承 MyBatis-Plus 的 IService 4. **查询接口默认分页** - 所有返回列表的查询接口,默认进行分页处理 ### 查询方式选择 | 场景 | 推荐方式 | |:------|:---------| | 单表按 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 依赖 ```xml org.mapstruct mapstruct 1.5.5.Final ``` ### 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` |