# Java Backend Dev Workflow

> 规范设计、开发、修复、审查和验证 Java/Spring Boot 后端，并维护项目根目录的后端开发与设计契约及数据库表结构文档。覆盖 IDEA 工作流、架构与接口状态、依赖兼容性、SLF4J 日志、JavaDoc、DTO/VO、Service/Repository、OpenAPI/Knife4j、配置分层、数据库迁移、数据表文档和交付验证。用于后端方案设计、初始化、接口与持久化开发、数据库表总结或维护、依赖升级、问题排查、代码规范整理、本地联调、发布和部署准备。

- Skill: `rayekry777/java-backend-dev-workflow` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add rayekry777/java-backend-dev-workflow`
- Raw SKILL.md: https://api.skillmd.com/api/skills/rayekry777/java-backend-dev-workflow/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Productivity
- Author: Rayekry777 (https://skillmd.com/u/rayekry777)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/rayekry777/java-backend-dev-workflow

---


# Java 后端开发工作流

## 工作原则

- 默认处于开发阶段，以 IDEA Run/Debug 联调；除非用户要求，不长期启动服务，不提前生成 JAR、Docker 或部署产物。
- 只修改任务所需内容，保留用户的未提交改动、现有 `target/` 和无关文件。
- 先确认事实再实现；对可能变化的版本、兼容矩阵和官方用法查询当前官方资料，不凭记忆猜测。
- 修改源码时同步维护日志、注释、OpenAPI、测试和相关文档，不把它们留作事后补充。

## 后端开发与设计契约

- 将项目根目录 `BACKEND_DEVELOPMENT.md` 作为后端范围、架构、接口状态、数据演进、阶段和验证记录的维护入口。
- 将项目根目录 `DATABASE_SCHEMA.md` 作为当前数据库表、字段摘要、隔离边界、关系、索引、初始化数据和迁移版本的维护入口。
- 开始后端设计、开发、修复或审查前，先查找并完整读取该文档，再读取源码、配置、迁移、测试和 Git 状态；文档不得替代事实扫描。
- 文档缺失且任务涉及架构、接口、权限、数据库、配置或外部集成设计时，复制 [后端开发契约模板](assets/backend-development-template.md) 到项目根目录并按扫描结果填写。
- `DATABASE_SCHEMA.md` 缺失且项目已有数据库迁移、建表 SQL 或持久化模型时，根据数据库结构真源生成；不得只凭 Entity、Mapper 或旧文档推断实际表结构。
- 设计任务先在文档中记录范围、现状证据、目标边界、接口状态、数据流、迁移、风险和验收；仅完成设计的能力标记“未实现”。
- 实现任务开始时将目标能力标记“开发中”，完成源码、权限、校验、测试、OpenAPI、编译和文档同步后才标记“已实现”。
- 接口、表结构、权限、配置、模块边界、外部集成、实施阶段或关键决策变化时，在同一任务内同步更新文档；简单内部重构且不改变契约时只追加必要验证记录。
- 状态只使用“未确认、未实现、开发中、已实现、已废弃”。存在类、DTO、前端调用或占位路由不等于已实现。
- OpenAPI 是 HTTP 契约真源，Flyway/Liquibase 历史是已执行数据库结构真源；开发文档只维护索引、决策、状态和验收，不复制整份生成文档或完整 DDL。
- 只读诊断或审查不自动改写项目文件，除非用户明确要求维护文档；交付时报告发现的文档偏差。

## 标准流程

1. **检查**：读取仓库约束、根目录后端开发契约、数据库表结构文档、构建文件、相关源码、配置、迁移、其他文档、测试和 Git 状态；识别现有日志与注释风格。
2. **同步现状**：用代码、OpenAPI、迁移和测试校正文档中的模块、接口和阶段状态，区分事实、设计和待确认项。
3. **设计**：明确接口契约、数据流、权限、事务、异常、兼容性和最小修改范围，并同步开发契约。
4. **实现**：完成必要源码、配置、测试和新增迁移，不扩大业务范围；持续维护目标能力状态。
5. **校验**：检查日志、注释、开发契约、OpenAPI 和依赖树，再按风险执行 Maven 验证并记录实际结果。
6. **交付**：说明源码与契约变化、验证结果、未验证项、风险和 IDEA 联调步骤，并提供规范的建议 Git 提交信息；除非用户明确要求，不执行暂存、提交或推送。

## 代码与模型

### DTO、VO 与 Entity

- 新增的无状态 DTO、查询条件和简单 VO 优先使用 Java `record`。
- `record` 组件直接承载 `@Schema` 和 Jakarta Validation；调用方使用 `componentName()`，不得伪造 Getter、Setter 或可变 Builder。
- 对集合、Map、数组等可变成员执行必要的防御性复制；跨字段不变量在紧凑构造器中校验。
- Entity、MyBatis 依赖无参构造或 Setter 的对象、存在合法状态变化的模型和依赖继承的模型使用普通 `class`。
- 仅在不破坏 Jackson、Spring MVC、MyBatis、模板表达式或第三方框架约定时迁移旧模型；同步替换 Setter 和不适用的 `BeanUtils.copyProperties`。

### JavaDoc 与行内注释

- Service 接口及实现类必须有类级 JavaDoc；接口说明业务能力，实现类说明实现职责。
- Service 接口每个方法及实现类每个公开方法必须有简洁方法级 JavaDoc，说明业务动作和关键约束。
- Repository 类及其公开方法必须有 JavaDoc；私有方法只在存在复杂规则、边界或格式转换时注释。
- JavaDoc 放在 Spring、Lombok、事务等注解之前；仅在参数或返回值存在额外语义时写 `@param`、`@return`，禁止空模板。
- 行内注释解释原因、边界和业务规则，不复述代码；禁止流程编号、废弃代码和失效注释。
- 修改逻辑时同步修改注释；完成后扫描 Service 接口、实现类和 Repository，确认类与方法覆盖完整。

## 后台日志

- 使用 Lombok `@Slf4j` 和 SLF4J `{}` 占位符；禁止字符串拼接、`System.out`、`System.err` 和 `printStackTrace()`。
- 沿用现有模块标签；缺失时使用 `log.info("[模块或场景] 操作描述，字段={}", value)`。
- `debug` 记录诊断细节；`info` 记录启动、接口入口和重要状态变化；`warn` 记录可预期异常；`error` 记录未预期故障并传入异常对象。
- Controller 记录业务入口和必要关键参数；Service 只记录重要状态变化或外部调用结果，避免跨层重复。
- 不记录密码、JWT、密钥、完整手机号、身份证号、巨大请求体、集合或完整响应。
- 统一异常处理器已记录异常时，业务层不重复记录同一异常堆栈。

## 依赖版本兼容性

- 新增或升级依赖前确认 Java、Spring Boot、Spring Framework、Spring Cloud、构建插件和相关 Starter 的声明版本与实际解析版本。
- 对 Spring Boot、Spring Cloud、Springdoc、Knife4j、MyBatis、数据库驱动等强耦合组件，优先核对官方兼容矩阵、发布说明或 BOM。
- 优先由 Spring Boot 或组件官方 BOM 管理传递依赖；Starter 已集成的组件不得重复声明。
- 确需覆盖传递版本时说明原因，并确认不存在同一库多版本、重复实现或二进制 API 冲突。
- 修改后运行 `mvn dependency:tree`，按相关 `groupId`/`artifactId` 检查最终版本和来源；必要时使用 `mvn help:effective-pom` 或 Maven Enforcer。
- 兼容性结论至少包含：项目基础版本、目标依赖版本、传递核心版本、官方依据和依赖树结果。
- `compile` 只证明编译兼容；涉及自动配置、反射、序列化或 UI Starter 时执行最小运行时或端点验证。
- 遇到 `NoSuchMethodError`、`ClassNotFoundException` 或自动配置失败时，先按依赖树定位冲突，再采用官方支持的版本组合；禁止用放宽业务逻辑或盲目降级核心框架掩盖问题。

## OpenAPI 与 Knife4j

### UI 与依赖

- 默认只保留 Knife4j UI，入口为 `/doc.html`；除非用户明确要求，不同时开放多个文档 UI。
- 禁用或拦截 `/swagger-ui.html` 与 `/swagger-ui/**`，但保留 `/v3/api-docs`、`/v3/api-docs/**` 和 `/v3/api-docs/swagger-config`。
- Spring Boot 3 使用兼容的 `knife4j-openapi3-jakarta-spring-boot-starter`；Starter 已传递 Springdoc，禁止重复声明 UI Starter。
- 启用 Knife4j 增强功能前验证其与 Springdoc 的运行时兼容性；发生二进制冲突时采用官方兼容组合。

### Controller 与模型契约

- Controller 类使用 `@Tag`；每个接口使用 `@Operation`，并声明稳定、唯一、语义化的 `operationId`。
- 路径参数和含义不明显的查询参数使用 `@Parameter`。
- 使用 `@ApiResponses` 声明真实成功状态及适用的 `400/401/403/404/409/500`；错误响应引用统一 Schema。
- 认证项目声明标准 Bearer JWT；私有操作声明 `security`，公开操作使用 `@SecurityRequirements` 明确取消继承认证。
- DTO、VO 等实际接口模型使用 `@Schema`；Entity 未直接作为接口模型时不强制添加 Swagger 注解。
- `@Schema` 与 Jakarta Validation 必须表达一致的必填、范围、长度和格式；Controller 使用 `@Valid`/`@Validated` 启用运行时校验。
- 按语义声明 `requiredMode`、`example`、`allowableValues`、`format`、完整 `pattern`、`minimum` 和 `maximum`。
- 邮箱使用 `format: email`；分页满足 `page >= 1`、`1 <= size <= 100`；跨端 ID 类型保持一致。
- 禁止让稳定结构的裸 `JsonNode` 生成 `{}`；动态对象声明 `additionalProperties`，动态数组声明 `items`。
- 配置 API 标题、语义版本和环境无关 Server。

### 文档验证

- 修改接口或模型后验证实际 `/v3/api-docs`，不得用旧导出文件代替。
- 至少校验 `/doc.html`、OpenAPI 数据端点、非目标 UI、路径与方法、全部 `$ref`、安全声明、错误响应、关键 Schema、元信息和唯一 `operationId`。
- 使用非法请求验证 Jakarta Validation 确实生效；源码或配置变化后重启应用再导出 JSON/YAML，并核对生成时间和关键内容。

## 配置、数据与文档

### 配置分层

- `.env` 只保存本地或部署环境注入的变量值，例如数据库、缓存、密钥、第三方凭据和端口；不得在其中复制 YAML 层级结构、业务默认值、Profile 选择或功能开关说明。`.env` 必须加入 `.gitignore`，真实凭据不得提交；可提交脱敏的 `.env.example` 作为变量模板。
- `application.yml` 只保存所有环境共用的配置结构、非敏感默认值和环境变量占位符。公共配置只能定义一次；必填敏感配置使用无默认值占位符，只有安全且通用的基础参数允许设置默认值。
- `application-{profile}.yml` 只保存当前 Profile 的差异配置，例如开发、测试和生产的功能模式、日志级别、初始化策略和文档开关，并使用 `spring.config.activate.on-profile` 声明适用环境。不得重复复制公共数据库、Redis、JWT、OSS 等完整配置，除非明确是该环境的差异覆盖；生产配置必须显式关闭开发初始化、调试文档和宽松开发选项。
- 一个配置项只能有一个规范键名和一个读取入口；禁止为同一能力维护多个命名空间、环境变量或默认值。优先使用 Spring Boot 标准键，自定义业务配置统一放到 `ray.*`；环境变量统一使用大写下划线形式，并保持与 YAML 键的可追溯映射。
- Profile 激活逻辑只能有一个明确来源，默认环境必须显式记录，例如 `spring.profiles.active: ${SPRING_PROFILES_ACTIVE:dev}`。文档、代码和配置中的键名必须一致；测试配置必须覆盖主配置实际读取的标准键，不能使用未被绑定的同名自定义前缀。
- 审查配置时检查：公共配置是否被 Profile 重复复制；同一功能是否存在多个前缀、环境变量或默认值；`.env` 是否混入结构化配置；`application.yml` 是否写入密码、密钥、AccessKey 或 AppSecret；必填变量是否错误地默认为空；Profile 行为是否与文档一致；生产是否继承通配跨域、SQL 初始化或调试日志等宽松默认值；同一功能是否存在未说明的重复定义或覆盖。
- 推荐文件结构为：

  ```text
  .env                    # 本地真实变量，不提交
  .env.example            # 脱敏变量模板，可提交
  application.yml         # 公共结构与占位符
  application-dev.yml     # 开发环境差异
  application-test.yml    # 测试环境差异
  application-prod.yml    # 生产环境差异
  ```

  配置加载关系为：`.env / 外部环境变量 -> application.yml 公共结构 -> application-{profile}.yml 环境差异覆盖 -> 最终 Spring Environment`。
- 当前项目审查示例：根目录 `.env` 已被 `.gitignore` 忽略但包含高敏感凭据，应提供 `.env.example`；`application-test.yml` 的 `ray.redis.*` 与主配置使用的 `spring.data.redis.*` 不一致；`application-dev.yml` 的微信登录模式与文档中的 dev/test MOCK 约定不一致；`application.yml` 的 WebSocket `allowed-origins` 默认 `*` 不应作为生产默认值；专题文档中关于 `application-dev.yml` 已忽略且未跟踪的描述需要记录为文档偏差。
- IDEA 后端连接开发机可达的虚拟机 IP，不写 `localhost`；数据库、Redis 等开发依赖端口只向开发机开放。
- README 为虚拟机 Docker 依赖提供最简启动、状态、日志和停止命令。

### 数据库迁移

- 数据库结构只通过新的有序迁移演进；不修改已执行迁移，不清空、重建或重置数据库。
- 启动应用前检查是否存在自动执行 SQL、清库、重建或不可逆初始化逻辑；存在风险时不擅自启动。

### 数据库表结构文档

- 在项目根目录维护 `DATABASE_SCHEMA.md`；首次生成时扫描全部 Flyway/Liquibase 迁移、基线和建表 SQL，以按顺序执行后的最终结构为准。
- 文档至少记录当前结构版本、表清单、用途、隔离范围、关键字段、主键、唯一约束、重要索引、实际外键、主要逻辑关系、初始化数据和待建表。
- 明确区分数据库实际声明的外键与仅由应用维护的逻辑关联，不把 Entity 注解或字段命名误写为数据库约束。
- 合并基线和增量迁移的效果；已被后续迁移删除、改名或替换的字段、索引和约束不得作为当前结构保留。
- 新增或修改迁移时，在同一任务内同步更新受影响表、关系、索引、迁移版本和演进状态；只改业务代码且表结构未变化时不机械重写。
- 多租户项目必须标明每张表的平台级、租户级或租户加门店级隔离范围，并记录临时默认租户值、兼容桥接和后续移除条件。
- 校验文档覆盖全部当前业务表，表数量和表名与迁移结果一致；排除 `flyway_schema_history` 等框架元数据表，除非项目要求记录。
- 文档是便于开发和评审的结构摘要，不复制完整 DDL；实际数据库结构仍以迁移历史为真源。

### 文档与接口状态

- 优先维护根目录 `BACKEND_DEVELOPMENT.md` 和 `DATABASE_SCHEMA.md`；沿用其他专题文档结构，README 只做导航，不堆接口或表字段明细。
- 接口状态只使用“未确认、未实现、开发中、已实现、已废弃”；仅在实现、权限、校验、测试、OpenAPI、说明和编译全部完成后标记“已实现”。
- 接口、架构、权限、配置、数据库或目录变化时同步开发契约；专题细节放到独立文档并从契约链接。
- 仅完成设计时统一标记“未实现”。

## Maven 验证矩阵

1. 先运行 `mvn -version`；不可用时再使用仓库现有 Maven Wrapper，不下载 Maven。
2. 小型源码或配置修改：运行相关模块 `compile`。
3. 业务行为修改：运行相关测试，再编译。
4. 认证、持久化、迁移或公共基础设施修改：运行相关集成测试，必要时运行 `test`。
5. Controller、DTO 或 OpenAPI 修改：运行实际文档端点契约测试，再编译。
6. 依赖升级：运行依赖树、编译及相应的最小运行时验证。
7. 仅在用户明确进入发布或部署阶段时执行 `package`、`install`、`deploy` 或新增部署产物。

## Git 提交信息

- 每次产生文件变更的交付都提供一份可直接复制的 Conventional Commits 建议，不等待用户再次询问。
- 使用 `<type>(<scope>): <中文简述>` 标题；优先选择 `feat`、`fix`、`refactor`、`docs`、`test`、`perf`、`build`、`ci`、`chore`。
- `scope` 使用稳定的领域或模块名，如 `saas`、`auth`、`tenant`、`employee`、`order`、`db`、`docs`；一次提交涉及同一目标的多层改动时使用业务领域，不罗列目录。
- 标题准确描述单一逻辑目标，避免“更新代码”“修复问题”等空泛文字；正文使用短列表总结关键变化与验证结果。
- 存在不兼容变更时在类型后加 `!`，并在正文末尾添加 `BREAKING CHANGE: ...`。
- 若改动包含多个彼此独立的逻辑主题，建议拆成多条提交信息并说明各自文件范围，不把所有变化强塞进一个提交。
- 只生成建议文本，不执行 `git add`、`git commit`、`git push`，除非用户在当前请求中明确授权。

模板：

```text
type(scope): 简短说明

- 关键变化一
- 关键变化二
- 验证：实际执行的测试或编译结果
```

## 交付清单

- 说明源码、配置、迁移、日志、注释、根目录开发契约、数据库表结构文档、OpenAPI 和依赖变化。
- 列出敏感信息与重复日志检查、依赖兼容结论、测试和编译结果。
- 明确未验证项、剩余风险、IDEA 联调步骤，以及是否延后 JAR、Docker 和部署工作。
- 附上与本次实际改动一致的建议 Git 提交信息，并明确未代用户提交。

