7.8 KiB
label_backend 标准目录扁平化设计
日期: 2026-04-14
范围: label_backend 主工程 Java 包结构调整
目标: 将当前按业务域分层的 com.label.module.* 结构重组为符合《微服务开发规范文档》的扁平标准目录结构,同时保持现有业务行为不变。
1. 背景与现状
当前项目主代码位于 src/main/java/com/label,整体结构分为两部分:
com.label.common.*:放置公共能力,如配置、异常、AOP、鉴权、Redis、状态机、存储与 AI 客户端com.label.module.*:按业务域划分的模块目录,如user、task、source、annotation、export、config、video
现有结构具备一定领域边界,但与《微服务开发规范文档》中规定的标准扁平目录结构不一致。后续如果继续沿用两套组织方式,会增加新代码接入成本,也会让公共能力与业务层级的归属变得不稳定。
2. 设计目标
本次调整目标如下:
- 将主代码目录统一调整为规范文档中的扁平结构
- 保持包职责清晰,按“层级职责”而不是“业务模块”组织类
- 在不改变业务逻辑和接口行为的前提下完成迁移
- 规范包归属与少量命名,不引入新的技术分层
- 为后续新增功能提供统一、可预测的目录组织方式
3. 明确不做的事情
为控制改造范围,本次不包含以下内容:
- 不新增
service.impl - 不将
dto拆分为request、response、common - 不主动修改接口 URL、接口契约或返回结构
- 不进行与目录调整无关的业务重构
- 不改造数据库结构、SQL 文件或资源文件布局
4. 目标目录结构
目标结构定义如下:
src/main/java/com/label/
├── annotation/
├── aspect/
├── common/
│ ├── ai/
│ ├── context/
│ ├── exception/
│ ├── redis/
│ ├── result/
│ ├── shiro/
│ ├── statemachine/
│ └── storage/
├── config/
├── constant/
├── controller/
├── dto/
├── entity/
├── event/
├── feign/
├── listener/
├── mapper/
├── scheduled/
├── service/
├── typehandler/
├── util/
└── LabelBackendApplication.java
说明:
common只保留真正跨业务复用的基础能力config从原common.config提升到顶层annotation与aspect从原common.aop中拆分event与listener分离,避免事件定义与监听逻辑混放controller、service、mapper、entity、dto全部收敛为顶层扁平结构
5. 包迁移规则
5.1 顶层迁移规则
com.label.module.*.controller->com.label.controllercom.label.module.*.service->com.label.servicecom.label.module.*.mapper->com.label.mappercom.label.module.*.entity->com.label.entitycom.label.module.*.dto->com.label.dtocom.label.module.annotation.event->com.label.event- 事件监听类 ->
com.label.listener com.label.common.config->com.label.configcom.label.common.aop中注解类 ->com.label.annotationcom.label.common.aop中切面类 ->com.label.aspect
5.2 典型映射示例
com.label.module.user.controller.AuthController->com.label.controller.AuthControllercom.label.module.user.service.UserService->com.label.service.UserServicecom.label.module.task.mapper.AnnotationTaskMapper->com.label.mapper.AnnotationTaskMappercom.label.module.source.entity.SourceData->com.label.entity.SourceDatacom.label.module.user.dto.LoginRequest->com.label.dto.LoginRequestcom.label.common.aop.OperationLog->com.label.annotation.OperationLogcom.label.common.aop.AuditAspect->com.label.aspect.AuditAspectcom.label.module.annotation.event.ExtractionApprovedEvent->com.label.event.ExtractionApprovedEventcom.label.module.annotation.service.ExtractionApprovedEventListener->com.label.listener.ExtractionApprovedEventListenercom.label.common.config.RedisConfig->com.label.config.RedisConfig
5.3 命名策略
- 以“最小必要变更”为原则,优先迁移包路径,不主动重命名类
- 仅在类职责与包语义明显不匹配时做必要归位
- 现阶段主代码类名不存在重名冲突,因此不需要为扁平化提前引入前缀或后缀
6. 实施顺序
为降低迁移风险,实际执行采用“目标一次性扁平化,操作分阶段迁移”的方式。
阶段 1:基础公共层归位
先迁移以下内容,建立新骨架:
annotationaspectconfigeventlistener
目标是先完成最基础的结构纠偏,并尽早暴露切面、配置和事件扫描问题。
阶段 2:数据承载层迁移
再迁移下列包:
entitydtomapper
这些类依赖通常较窄,适合优先扁平化,也能及早验证 MyBatis 相关扫描与引用是否正常。
阶段 3:业务服务层迁移
迁移所有业务服务类到 service,原则如下:
- 不新增实现层
- 不调整现有业务编排
- 只修正导包、注解引用和必要的包路径依赖
阶段 4:控制层迁移
最后迁移全部控制器到 controller。控制层依赖最广,放在后面可以减少中间态反复修改。
阶段 5:启动与扫描校正
统一检查并修正以下内容:
@MapperScan- 组件扫描隐式路径
- OpenAPI 相关配置
- 事件监听与切面装配
- 测试代码中的旧包引用
阶段 6:编译与回归验证
迁移完成后进行全量编译与测试回归,确认结构调整没有引入行为回归。
7. 风险与控制策略
风险 1:导包失效
大量类迁移后,主代码和测试代码中的 import 会同时失效。
控制策略:
- 按阶段迁移并同步修复引用
- 每个阶段结束后至少执行一次编译检查
风险 2:Spring 扫描路径异常
若配置类、切面、监听器或 Mapper 的扫描路径与旧包结构耦合,迁移后可能导致 Bean 缺失。
控制策略:
- 显式检查启动类与配置类中的扫描配置
- 将路径校正作为独立阶段处理
风险 3:事件监听失效
监听器从 service 拆到 listener 后,若注解或组件扫描不正确,会导致事件未被消费。
控制策略:
- 迁移时同步校验事件类与监听器依赖关系
- 通过现有集成测试覆盖事件链路
风险 4:测试回归失败
测试代码同样引用旧包名,若只改主代码,会造成测试集整体失效。
控制策略:
- 测试代码与主代码同步迁移
- 将
mvn test作为最终验收门槛
8. 验收标准
本次结构调整完成后,应满足以下标准:
src/main/java/com/label/module目录被完全移除- 主代码包结构符合标准扁平目录规范
- 项目能够成功编译
- 现有测试能够通过,至少覆盖当前可运行的启动测试、单元测试和集成测试
- 调整范围内不存在残留旧包引用
9. 实现原则
执行本设计时应遵循以下原则:
- 先保证结构归位,再追求风格统一
- 先保证行为不变,再做命名优化
- 所有改动以“目录标准化”为中心,不引入额外架构决策
- 每次修改都要让工程更接近规范,而不是制造新的混合结构
10. 结论
本次改造将 label_backend 从“按业务域分层 + 公共包混合”的现状,统一整理为规范文档定义的扁平标准目录结构。该调整不会改变系统能力边界,但会显著提升代码组织一致性、后续开发可预测性以及新成员理解成本。
实施时采用“目标结构一次确定、操作按阶段推进”的方式,以降低大规模包迁移带来的编译与装配风险。