1016 字
约 3 分钟
6
S06-J03 · 代码生成:注解处理器与脚手架
适用读者:纠结"生成代码要不要提交到 Git"的人。
前置:S06-B02。
口径:A-1856(MyBatis-Plus AutoGenerator)主讲归 S08,本篇只讲"生成策略"。
覆盖旧文:A-1856(90,duplicate_ref→ S08)。
覆盖扩展:E-S06-011(生成物是否进仓库)。
上一篇:S06-J02 · 序列化陷阱:版本兼容、循环引用与反序列化安全
下一篇:S06-A01 · 组件选型治理。
1. 一句话结论
代码生成分两类:编译期生成(Lombok/MapStruct,不进仓库)与一次性脚手架(实体/Mapper,通常进仓库)。判断标准是"生成物是否需要被 Review 与修改"。
| 类型 | 例子 | 进仓库 | 原因 |
|---|---|---|---|
| 编译期生成 | Lombok、MapStruct、QueryDSL | ❌ | 每次构建都会再生成,进仓库等于双份 |
| 一次性脚手架 | MyBatis-Plus AutoGenerator、Swagger 代码 | ✅(多数团队) | 需要人改、需要 diff |
| 配置驱动生成 | protobuf、OpenAPI 客户端 | ⚠️ 视情况 | 生成物大、频繁变 |
2. Lombok 与 MapStruct 的差别(B02 的延伸)
| 维度 | Lombok | MapStruct |
|---|---|---|
| 生成什么 | getter/setter/构造器 | 对象映射实现类 |
| 生成时机 | 编译期改 AST | 编译期生成 .java |
| 调试 | 看不到源码 | 能在 target/generated-sources 里看到 |
| IDE | 需插件 | 生成后可见,无需插件 |
判据:"我需要看到生成的代码吗?" 需要 → MapStruct 式(生成源文件);不需要 → Lombok 式(改 AST)。
3. 生成物是否进仓库(E-S06-011)
| 选项 | 优点 | 缺点 |
|---|---|---|
| 进仓库 | diff 可 Review、可直接改、IDE 友好 | 生成器升级时冲突、双份维护 |
| 不进仓库(构建期生成) | 单一事实来源 | 新人要先跑一次生成、IDE 可能标红 |
判据三问:
① 生成物会不会被人手工修改?
├── 会 → 进仓库(否则改动会被覆盖)
└── 不会 → ② 生成是否稳定(同输入同输出)?
├── 稳定 → 可不进仓库(构建期生成)
└── 不稳定 → ③ 必须固定生成器版本,并进仓库
实践共识:脚手架生成一次就提交,之后当普通代码维护;编译期生成的(Lombok/MapStruct 实现类)不进仓库。
4. 生成器的三个治理点
| 点 | 说明 |
|---|---|
| 版本锁定 | 生成器升级可能改变输出 → 必须锁版本(同 S06-A02 的可复现) |
| 生成范围 | 只生成 DTO/实体/Mapper,不要生成业务逻辑 |
| 与手写代码隔离 | 生成到独立目录(如 generated/),避免人手改后被覆盖 |
5. 五个误区
| 误区 | 真相 |
|---|---|
| "生成代码不用管" | 生成器升级会造成大 diff |
| "所有生成物都该进仓库" | 编译期生成的不该 |
| "生成器越强越好" | 生成业务逻辑会导致不可维护 |
| "生成的代码可以随便改" | 下次生成会被覆盖(除非改变生成模板) |
| "Lombok 与 MapStruct 一样" | 一个改 AST,一个生成源文件 |
6. 自检
- 两类代码生成的区别是什么?各自是否进仓库?
- Lombok 与 MapStruct 在"可见性"上的差别?
- 判断"生成物是否进仓库"的三问是什么?
- 生成器为什么要锁版本?
- 为什么"生成的代码不该包含业务逻辑"?
7. 下一篇
S06-A01 · 组件选型治理:JDK / Guava / Hutool / Lombok 的边界
进阶层结束,架构师层开始:引入一个库的真实成本,以及团队级的选型纪律。
本篇属于系列《S06 · Java 工程化与组件》。旧文来源:A-1856(duplicate_ref → S08);扩展点 E-S06-011。
S06-J03 · 代码生成:注解处理器与脚手架
https://www.clxhxhhr.top/posts/5263/ 评论
0 条
还没有评论,先写一条吧。