Java项目基础架构(一)| 工程架构选型指南

Java项目基础架构(一)| 工程架构选型指南

  • 前言
  • 一、单工程(严格分层):小团队/短周期项目的高效之选
    • [1. 适用场景](#1. 适用场景)
    • [2. 核心优势](#2. 核心优势)
    • [3. 模板参考](#3. 模板参考)
      • [1. 统一返回类 `core/model/Result.java`](#1. 统一返回类 core/model/Result.java)
      • [2. BizErrorCodeEnum.java](#2. BizErrorCodeEnum.java)
      • [3. 主配置文件 `resources/config/application.yml`](#3. 主配置文件 resources/config/application.yml)
    • [4. 核心约束(必须遵守)](#4. 核心约束(必须遵守))
      • [1. 分层调用约束(高内聚低耦合核心)](#1. 分层调用约束(高内聚低耦合核心))
      • [2. 数据安全约束(合规核心)](#2. 数据安全约束(合规核心))
      • [3. 权限约束(RBAC核心)](#3. 权限约束(RBAC核心))
      • [4. 代码规范约束(团队协作核心)](#4. 代码规范约束(团队协作核心))
  • 二、父子工程(按职责拆分):中大型项目的可扩展之选
    • [1. 适用场景](#1. 适用场景)
    • [2. 核心优势](#2. 核心优势)
    • [3. 模板参考](#3. 模板参考)
      • [1. 依赖单向性(禁止循环依赖)](#1. 依赖单向性(禁止循环依赖))
      • [2. 模块职责唯一(禁止跨职责写代码)](#2. 模块职责唯一(禁止跨职责写代码))
      • [3. 打包部署规则](#3. 打包部署规则)

前言

工程架构选型的核心逻辑是"宁简勿繁,按需设计 "------没有绝对最优的方案,只有最贴合当前场景的选择。

以下结合大厂实践经验,清晰拆解两类工程架构的适用场景与核心优势:

一、单工程(严格分层):小团队/短周期项目的高效之选

1. 适用场景

  • 核心人群:个人开发者、毕业设计项目、3人以内小团队
  • 项目特征:业务逻辑相对简单、迭代周期短、无需多团队协作
  • 典型案例:高校课程设计中的学生管理系统、小型工具类应用、单一功能模块开发

2. 核心优势

单工程的价值在于"极简高效、低门槛落地":

  • 开发效率拉满:无需额外处理模块拆分、依赖管理等复杂配置,快速启动开发,缩短上线周期;
  • 维护成本极低:严格遵循"Controller→Service→Mapper→Model"分层规范,足以支撑小项目的代码可读性,避免架构过度设计带来的"形式感大于实用性";
  • 无额外踩坑点:减少父子工程可能出现的依赖冲突、模块间调用混乱等问题,实际开发体验远优于"为了拆分而拆分"的复杂架构。

3. 模板参考

以下以学生管理系统为例:

bash 复制代码
student-management-system/                  # 【命名规范】项目根目录(英文小写,无中文/拼音/特殊字符,便于CI/CD部署)
├── README.md                               # 【必备】项目核心说明(含架构设计、部署流程、权限说明、维护手册)
├── pom.xml                                 # 【依赖管理】Maven核心配置(统一版本、私服、组件依赖)
├── .gitignore                              # 【版本管控】Git忽略规则(过滤IDE配置、日志、编译产物、敏感配置)
├── .editorconfig                           # 【编码规范】编辑器统一配置(缩进、编码、换行符,团队协作无格式冲突)
├── .checkstyle.xml                         # 【代码校验】CheckStyle规则(对齐阿里Java开发手册,编译时强制校验)
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/xxx/edu/student/        # 【包命名】域名反转+领域+服务名(xxx=企业域名/学校缩写,edu=教育领域)
│   │   │       ├── StudentManagementApplication.java  # 【启动规范】唯一启动类(根包下,仅负责启动,无业务逻辑)
│   │   │       ├── api/                    # 【接口层】前后端/跨服务对接唯一契约层(无业务逻辑,仅定义交互标准)
│   │   │       │   ├── controller/         # 【接口入口】仅参数接收/返回,代码≤10行/方法,禁止业务逻辑
│   │   │       │   │   ├── UserController.java        # 用户模块(登录/权限/账号管理,需加接口鉴权注解)
│   │   │       │   │   ├── StudentController.java     # 学生模块(学籍/信息管理,需加数据权限注解)
│   │   │       │   │   ├── ClazzController.java       # 班级模块(班级信息/班课管理)
│   │   │       │   │   ├── CourseController.java      # 课程模块(课程/选课/排课,需加操作审计注解)
│   │   │       │   │   ├── ScoreController.java       # 成绩模块(录入/统计/导出,需加数据脱敏返回)
│   │   │       │   │   ├── AttendanceController.java  # 考勤模块(记录/统计/提醒)
│   │   │       │   │   └── SysController.java         # 系统模块(字典/配置/日志查询,运维必备)
│   │   │       │   ├── dto/                # 【数据传输】仅字段+校验注解,无业务逻辑,前后端数据交互唯一载体
│   │   │       │   │   ├── user/           # 按业务模块拆分,便于维护和复用
│   │   │       │   │   │   ├── req/        # 入参DTO(前端传入,需做参数合法性、防XSS校验)
│   │   │       │   │   │   │   ├── UserLoginReq.java          # 登录入参(账号/密码/验证码,需加密码密文传输校验)
│   │   │       │   │   │   │   ├── UserAddReq.java            # 新增用户入参(含角色ID,需做权限校验)
│   │   │       │   │   │   │   └── UserQueryReq.java         # 用户查询入参(含分页,需做数据范围过滤)
│   │   │       │   │   │   └── resp/       # 出参DTO(返回前端,需做敏感字段脱敏)
│   │   │       │   │   │       ├── UserLoginResp.java         # 登录出参(Token/用户信息,需加Token过期时间)
│   │   │       │   │   │       └── UserInfoResp.java          # 用户信息出参(手机号/身份证脱敏)
│   │   │       │   │   ├── student/        # 学生模块DTO(入参/出参分离,避免前后端耦合)
│   │   │       │   │   ├── clazz/
│   │   │       │   │   ├── course/
│   │   │       │   │   ├── score/
│   │   │       │   │   ├── attendance/
│   │   │       │   │   └── sys/            # 系统模块DTO(字典/配置)
│   │   │       │   ├── enums/              # 【枚举规范】禁止魔法值,统一管理状态/类型/错误码
│   │   │       │   │   ├── BizErrorCodeEnum.java          # 全局错误码(200成功/4xx客户端/5xx服务端/6xx业务,需分级)
│   │   │       │   │   ├── UserTypeEnum.java           # 用户类型(ADMIN/TEACHER/STUDENT/PARENT,RBAC权限核心)
│   │   │       │   │   ├── StudentStatusEnum.java      # 学生状态(NORMAL/LEAVE/GRADUATE/TRANSFER,学籍管理)
│   │   │       │   │   ├── ScoreLevelEnum.java         # 成绩等级(A/B/C/D/F/EXCELLENT,成绩统计)
│   │   │       │   │   ├── AttendanceStatusEnum.java   # 考勤状态(PRESENT/ABSENT/LATE/LEAVE,考勤统计)
│   │   │       │   │   └── DictTypeEnum.java           # 字典类型(GENDER/MAJOR/COURSE_TYPE,系统配置)
│   │   │       │   ├── vo/                 # 【视图对象】前端展示专用,区别于DTO(如列表项简化、组合字段)
│   │   │       │   │   ├── StudentListItemVO.java      # 学生列表项(仅展示学号/姓名/班级/状态,减少数据传输)
│   │   │       │   │   ├── CourseScoreVO.java          # 课程成绩VO(课程名+分数+等级+排名,组合多表数据)
│   │   │       │   │   └── AttendanceStatsVO.java      # 考勤统计VO(学生名+出勤次数+缺勤次数+出勤率)
│   │   │       │   └── feign/              # 【扩展预留】Feign客户端(对接其他微服务,如教务系统/缴费系统)
│   │   │       │       └── EduPayFeignClient.java      # 缴费系统对接(多系统集成必备)
│   │   │       ├── core/                   # 【通用核心】全项目复用,无业务侵入,组件化核心
│   │   │       │   ├── config/             # 【配置规范】全局通用配置,无业务相关,支持配置中心
│   │   │       │   │   ├── CorsConfig.java             # 跨域配置(生产环境限定前端域名,禁止*)
│   │   │       │   │   ├── MyBatisPlusConfig.java      # MP配置(分页/自动填充/乐观锁/多租户,数据隔离)
│   │   │       │   │   ├── TransactionConfig.java      # 事务配置(强制rollbackFor=Exception,事务一致性)
│   │   │       │   │   ├── WebConfig.java              # Web配置(注册拦截器、静态资源、消息转换器)
│   │   │       │   │   ├── JasyptConfig.java           # 敏感配置加密(数据库密码/Token密钥,数据安全)
│   │   │       │   │   ├── SecurityConfig.java         # 安全配置(Spring Security/Sa-Token,接口鉴权)
│   │   │       │   │   ├── Knife4jConfig.java          # 接口文档配置(Knife4j/Swagger,前后端协作)
│   │   │       │   │   ├── RedisConfig.java            # Redis配置(缓存/分布式锁/幂等性,高性能核心)
│   │   │       │   │   └── MonitorConfig.java          # 监控配置(Actuator/Prometheus,运维监控)
│   │   │       │   ├── constant/           # 【常量规范】禁止魔法值,按功能分类
│   │   │       │   │   ├── DateConstant.java           # 日期格式(YYYY-MM-DD HH:mm:ss,统一时间格式)
│   │   │       │   │   ├── RegexConstant.java          # 正则(学号/手机号/身份证/邮箱,数据校验)
│   │   │       │   │   ├── StudentConstant.java        # 学生业务常量(学号前缀/年级规则/学籍有效期)
│   │   │       │   │   ├── SecurityConstant.java       # 安全常量(Token过期时间/加密盐值/权限前缀)
│   │   │       │   │   └── CacheConstant.java          # 缓存常量(缓存键前缀/过期时间,缓存管理)
│   │   │       │   ├── exception/          # 【异常体系】分级处理,统一返回,避免泄露敏感信息
│   │   │       │   │   ├── BusinessException.java      # 业务异常(已知错误,如"学号已存在",用户可感知)
│   │   │       │   │   ├── SystemException.java        # 系统异常(未知错误,如数据库连接失败,隐藏详情)
│   │   │       │   │   ├── AuthException.java          # 认证异常(Token过期/无权限,统一返回401/403)
│   │   │       │   │   ├── GlobalExceptionHandler.java # 全局异常处理器(统一返回R<T>,前端无需适配多格式)
│   │   │       │   │   └── validation/                 # 【自定义校验】复用性优先,避免重复校验逻辑
│   │   │       │   │       ├── StudentNo.java          # 学号校验注解(2024开头+8位数字,业务规则校验)
│   │   │       │   │       ├── StudentNoValidator.java # 学号校验器实现(可扩展多规则)
│   │   │       │   │       ├── IdCard.java             # 身份证校验注解(18位,含校验位,数据合法性)
│   │   │       │   │       └── IdCardValidator.java    # 身份证校验器实现
│   │   │       │   ├── interceptor/        # 【拦截器】通用型,无业务逻辑,前置处理请求
│   │   │       │   │   ├── TraceIdInterceptor.java     # 全链路TraceId(日志追踪,问题定位核心)
│   │   │       │   │   ├── AuthInterceptor.java        # 登录认证拦截器(校验Token,接口安全)
│   │   │       │   │   ├── DataScopeInterceptor.java   # 数据权限拦截器(按角色过滤数据,RBAC核心)
│   │   │       │   │   └── OperateLogInterceptor.java  # 操作审计拦截器(记录操作用户/IP/内容,审计合规)
│   │   │       │   ├── model/              # 【通用模型】全项目复用,无业务字段,标准化数据结构
│   │   │       │   │   ├── R.java                      # 统一返回类(所有接口必须返回,前后端交互标准)
│   │   │       │   │   ├── PageParam.java              # 分页入参(所有分页接口统一,避免分页参数混乱)
│   │   │       │   │   ├── PageData.java             # 分页出参(所有分页接口统一,含总条数/总页数)
│   │   │       │   │   ├── BasePO.java                 # 审计基类(创建时间/更新时间/创建人/更新人/逻辑删除,数据审计)
│   │   │       │   │   ├── OperateLogPO.java           # 操作日志实体(审计合规必备)
│   │   │       │   │   └── DictPO.java                 # 字典实体(系统配置核心)
│   │   │       │   ├── aspect/             # 【AOP】通用切面,解耦横切逻辑(审计/缓存/幂等性)
│   │   │       │   │   ├── OperateLogAspect.java       # 操作日志切面(注解式记录,减少重复代码)
│   │   │       │   │   ├── CacheAspect.java            # 缓存切面(注解式缓存,高性能)
│   │   │       │   │   └── IdempotentAspect.java       # 幂等性切面(注解式防重复提交,数据一致性)
│   │   │       │   └── util/               # 【工具类】私有化构造,禁止实例化,所有方法静态化
│   │   │       │       ├── StringUtil.java             # 字符串工具(脱敏/判空/格式化,敏感数据处理)
│   │   │       │       ├── DateUtil.java               # 日期工具(计算入学/毕业时间/年龄,时间处理)
│   │   │       │       ├── EncryptUtil.java            # 加密工具(密码MD5/AES/Token生成,数据安全)
│   │   │       │       ├── ExcelUtil.java              # Excel工具(导入导出学生信息/成绩,批量操作)
│   │   │       │       ├── TokenUtil.java              # Token工具(生成/解析/校验,认证核心)
│   │   │       │       ├── IpUtil.java                 # IP工具(获取客户端IP/归属地,审计/风控)
│   │   │       │       └── SecurityUtil.java           # 权限工具(获取当前用户/角色/数据范围,RBAC)
│   │   │       ├── biz/                    # 【业务核心】仅写业务逻辑,禁止数据操作/接口对接,高内聚低耦合
│   │   │       │   ├── user/               # 按业务模块拆分,便于团队分工(如A维护用户,B维护成绩)
│   │   │       │   │   ├── UserService.java            # 业务接口(定义能力,便于扩展/测试/降级)
│   │   │       │   │   └── UserServiceImpl.java        # 业务实现(核心逻辑,事务/幂等性/权限校验,业务核心)
│   │   │       │   ├── student/
│   │   │       │   │   ├── StudentService.java
│   │   │       │   │   └── StudentServiceImpl.java     # 含学号唯一性校验/学籍变更/年级计算等核心逻辑
│   │   │       │   ├── clazz/
│   │   │       │   ├── course/
│   │   │       │   ├── score/                          # 含成绩录入/统计/排名/等级转换等逻辑
│   │   │       │   ├── attendance/                     # 含考勤记录/统计/短信提醒等逻辑
│   │   │       │   └── sys/                            # 含字典管理/配置管理/日志查询等逻辑
│   │   │       ├── data/                   # 【数据访问】仅做CRUD,禁止业务逻辑,数据层与业务层解耦
│   │   │       │   ├── mapper/             # Mapper接口(MP注解/XML,仅数据操作,避免复杂SQL)
│   │   │       │   │   ├── UserMapper.java
│   │   │       │   │   ├── StudentMapper.java
│   │   │       │   │   ├── ClazzMapper.java
│   │   │       │   │   ├── CourseMapper.java
│   │   │       │   │   ├── ScoreMapper.java
│   │   │       │   │   ├── AttendanceMapper.java
│   │   │       │   │   ├── OperateLogMapper.java       # 操作日志Mapper(审计)
│   │   │       │   │   └── DictMapper.java             # 字典Mapper(系统配置)
│   │   │       │   ├── po/                 # 数据库实体(与表一一对应,仅字段+注解,ORM规范)
│   │   │       │   │   ├── UserPO.java                 # 用户表(id/账号/密码/姓名/用户类型/角色ID,RBAC)
│   │   │       │   │   ├── StudentPO.java              # 学生表(继承BasePO,含学号/姓名/班级/学籍信息)
│   │   │       │   │   ├── ClazzPO.java                # 班级表(班级编号/年级/专业/班主任ID)
│   │   │       │   │   ├── CoursePO.java               # 课程表(课程编号/课程名/学分/授课教师ID/课时)
│   │   │       │   │   ├── ScorePO.java                # 成绩表(学生ID/课程ID/分数/等级/录入时间/录入人)
│   │   │       │   │   ├── AttendancePO.java           # 考勤表(学生ID/课程ID/考勤状态/日期/备注)
│   │   │       │   │   ├── RolePO.java                 # 角色表(RBAC权限核心)
│   │   │       │   │   └── MenuPO.java                 # 菜单表(权限控制核心)
│   │   │       │   └── manager/            # 【扩展】数据管理器(复杂SQL/多表关联,封装数据操作)
│   │   │       │       └── StudentDataManager.java     # 学生数据管理器(多表关联查询,如学生+班级+课程)
│   │   │       └── facade/                 # 【外部对接】解耦业务与第三方,禁止业务逻辑,便于替换第三方
│   │   │           ├── cache/              # 缓存对接(Redis,高性能核心)
│   │   │           │   ├── UserCacheService.java        # 用户缓存(登录Token/用户信息,减少DB查询)
│   │   │           │   └── StudentCacheService.java     # 学生缓存(常用学生信息,提高查询效率)
│   │   │           ├── file/               # 文件对接(OSS/本地文件,文件存储)
│   │   │           │   └── FileService.java             # 文件上传下载(学生头像/成绩单/考勤表)
│   │   │           └── third/              # 第三方对接(多系统集成)
│   │   │               ├── SmsClient.java              # 短信客户端(考勤提醒/成绩通知/密码找回)
│   │   │               ├── MailClient.java             # 邮件客户端(成绩单/学籍证明发送)
│   │   │               └── PayClient.java              # 缴费客户端(学费/教材费缴纳,扩展)
│   │   └── resources/                      # 【资源规范】按功能/环境分类,禁止混乱,便于运维
│   │       ├── config/                     # 配置文件(环境隔离,禁止dev/prod混用)
│   │       │   ├── application.yml         # 主配置(通用参数,指定环境,支持配置中心)
│   │       │   ├── application-dev.yml     # 开发环境(本地数据库/DEBUG日志/Redis本地)
│   │       │   ├── application-test.yml    # 测试环境(测试库/INFO日志/Redis测试集群)
│   │       │   └── application-prod.yml    # 生产环境(生产库/INFO日志/Redis生产集群,禁止硬编码敏感信息)
│   │       ├── mapper/                     # MyBatis映射文件(仅复杂SQL,简单SQL用MP注解,SQL管理)
│   │       │   ├── StudentMapper.xml       # 学生复杂查询(如按年级/专业/状态统计)
│   │       │   ├── ScoreMapper.xml         # 成绩复杂查询(如班级平均分/年级排名)
│   │       │   └── AttendanceMapper.xml    # 考勤复杂统计(如月度考勤率/缺勤排名)
│   │       ├── script/                     # 数据库脚本(必须归档,便于版本回溯/运维)
│   │       │   ├── init/                   # 初始化脚本(建表/初始数据,环境搭建必备)
│   │       │   │   ├── 20240501_init_table.sql         # 建表脚本(用户/学生/课程/成绩等核心表)
│   │       │   │   ├── 20240501_init_admin.sql         # 初始化管理员账号(默认密码加密)
│   │       │   │   └── 20240501_init_dict.sql          # 初始化字典数据(性别/专业/课程类型)
│   │       │   ├── ddl/                    # 结构变更脚本(ALTER TABLE,版本化管理)
│   │       │   │   ├── 20240502_add_student_avatar.sql # 学生表新增头像字段
│   │       │   │   └── 20240503_add_score_rank.sql     # 成绩表新增排名字段
│   │       │   └── dml/                    # 数据变更脚本(INSERT/UPDATE/DELETE,运维操作)
│   │       │       └── 20240504_update_student_grade.sql # 更新2023级学生年级
│   │       ├── static/                     # 静态资源(加版本号,避免缓存问题)
│   │       │   ├── excel/                  # Excel模板(学生信息导入/成绩导出,批量操作)
│   │       │   │   ├── student_import_template_1.0.0.xlsx
│   │       │   │   └── score_export_template_1.0.0.xlsx
│   │       │   ├── html/                   # 前端静态页面(登录/报表预览,前后端分离可移除)
│   │       │   ├── js/                     # 前端JS(表单校验/数据展示)
│   │       │   └── css/                    # 前端CSS(样式统一)
│   │       ├── templates/                  # 模板文件(邮件/Excel模板,动态生成文件)
│   │       │   ├── mail/                   # 邮件模板(成绩通知/考勤提醒)
│   │       │   │   └── score_notice.ftl
│   │       │   └── excel/                  # Excel模板(动态填充数据)
│   │       ├── logback.xml                 # 日志配置(含TraceId/环境隔离/脱敏/滚动策略)
│   │       └── banner.txt                  # 启动横幅(品牌标识/版本信息)
│   └── test/                               # 【测试规范】结构与main完全对齐,核心代码覆盖率≥80%
│       └── java/
│           └── com/xxx/edu/student/
│               ├── biz/                    # 业务层测试(核心逻辑覆盖,单元测试+集成测试)
│               │   ├── student/
│               │   │   └── StudentServiceImplTest.java # 含正常流程/异常流程/边界值测试
│               │   └── score/
│               │       └── ScoreServiceImplTest.java   # 含成绩录入/统计/排名测试
│               ├── data/                   # 数据层测试(Mapper/PO,Mock测试,避免依赖DB)
│               │   └── mapper/
│               │       └── StudentMapperTest.java
│               ├── core/                   # 工具类测试(100%覆盖,保证通用能力可靠)
│               │   └── util/
│               │       └── StringUtilTest.java
│               └── integration/            # 集成测试(多模块交互,如Controller→Service→Mapper)
│                   └── StudentControllerIntegrationTest.java
└── target/                                 # 编译产物(Git忽略,CI/CD自动打包部署)                           

1. 统一返回类 core/model/Result.java

java 复制代码
import lombok.Data;
import java.io.Serializable;
import com.xxx.edu.student.api.enums.BizErrorCodeEnum;

/**
 * 统一返回类
 * 所有接口必须返回此类型
 */
@Data
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    private int code;
    private String message;
    private T data;
    private Long timestamp;
    private boolean success;

    // 私有构造,强制通过静态方法创建
    private Result() {
        this.timestamp = System.currentTimeMillis();
    }

    // 完全复用第二篇的静态方法
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(BizErrorCodeEnum.SUCCESS.getCode());
        result.setMessage(BizErrorCodeEnum.SUCCESS.getDefaultMessage());
        result.setData(data);
        result.setSuccess(true);
        return result;
    }

    public static <T> Result<T> success() {
        return success(null);
    }

    public static <T> Result<T> fail(BizErrorCodeEnum errorEnum) {
        Result<T> result = new Result<>();
        result.setCode(errorEnum.getCode());
        result.setMessage(errorEnum.getDefaultMessage());
        result.setData(null);
        result.setSuccess(false);
        return result;
    }

    public static <T> Result<T> fail(BizErrorCodeEnum errorEnum, String customMessage) {
        Result<T> result = new Result<>();
        result.setCode(errorEnum.getCode());
        result.setMessage(customMessage);
        result.setData(null);
        result.setSuccess(false);
        return result;
    }
}

2. BizErrorCodeEnum.java

java 复制代码
/**
 * 全局错误码枚举
 * 分类:200=成功,4xx=业务错误,5xx=系统错误
 */
public enum BizErrorCodeEnum {
    SUCCESS(200, "操作成功"),
    BUSINESS_ERROR(400, "业务参数错误"),
    PARAM_VALID_ERROR(4001, "参数校验失败"),
    RESOURCE_NOT_FOUND(404, "资源不存在"),
    SYSTEM_ERROR(500, "系统繁忙,请稍后再试"),
    AUTH_ERROR(401, "认证失败"),
    DATA_SCOPE_ERROR(403, "数据权限不足");

    private final int code;
    private final String defaultMessage;

    BizErrorCodeEnum(int code, String defaultMessage) {
        this.code = code;
        this.defaultMessage = defaultMessage;
    }

    public int getCode() {
        return code;
    }

    public String getDefaultMessage() {
        return defaultMessage;
    }
}

3. 主配置文件 resources/config/application.yml

yaml 复制代码
# 【主配置文件】仅配置通用参数,环境相关配置放在application-{env}.yml
# 设计原则:
# 1. 无环境相关配置,避免dev/prod混用
# 2. 配置项加详细注释,便于运维/新人理解
# 3. 支持配置中心(如Nacos/Apollo),生产环境必备

# 应用配置
spring:
  # 应用名称(链路追踪/监控平台/日志平台标识核心)
  application:
    name: student-management-system
  # 环境切换(dev/test/prod),通过启动参数--spring.profiles.active指定
  profiles:
    active: dev
  # 编码配置(强制UTF-8,避免中文乱码,必备)
  servlet:
    encoding:
      charset: UTF-8
      force: true
  # 日期格式化(统一时间格式,避免时区/格式混乱)
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8

# 服务器配置
server:
  # 端口(生产环境由运维指定,通过启动参数覆盖)
  port: 8080
  # 压缩配置(减少响应数据大小,提高接口性能,必备)
  compression:
    enabled: true
    mime-types: application/json,text/html,text/plain
    min-response-size: 1024

# MyBatis-Plus通用配置
mybatis-plus:
  # 下划线转驼峰(必须开启,匹配数据库字段命名规范)
  configuration:
    map-underscore-to-camel-case: true
    # 关闭二级缓存(生产环境建议用Redis缓存,避免二级缓存一致性问题)
    cache-enabled: false
  # 逻辑删除配置(匹配BasePO的isDeleted字段)
  global-config:
    db-config:
      logic-delete-field: isDeleted
      logic-delete-value: 1
      logic-not-delete-value: 0

# 监控配置(生产环境运维必备)
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus # 暴露监控端点
  metrics:
    tags:
      application: ${spring.application.name} # 监控指标打应用标签

# 日志配置(指定logback配置文件)
logging:
  config: classpath:logback.xml

4. 核心约束(必须遵守)

1. 分层调用约束(高内聚低耦合核心)

bash 复制代码
Controller → Service → Mapper/Feign/Facade
↑                           ↓
└───────────────────────────┘
禁止跨层调用:如Controller直接调Mapper、Service直接调第三方接口
禁止循环依赖:如A Service依赖B Service,B Service又依赖A Service

2. 数据安全约束(合规核心)

  • 敏感字段(身份证/手机号/密码)必须脱敏存储/传输;
  • 数据库密码/Token密钥必须加密(Jasypt),密钥通过启动参数注入;
  • 接口返回数据必须做敏感字段脱敏,禁止返回明文;
  • 生产环境禁止打印敏感信息到日志,必须脱敏。

3. 权限约束(RBAC核心)

  • 所有接口必须做认证(Token校验),公开接口(如登录)除外;
  • 所有接口必须做授权(角色/权限校验),避免越权访问;
  • 数据访问必须做范围过滤(如教师只能看自己班级的学生);
  • 操作日志必须记录(操作用户/IP/时间/内容/结果),便于审计。

4. 代码规范约束(团队协作核心)

  • 代码必须通过CheckStyle校验,禁止有Critical/Blocker问题;
  • 核心代码覆盖率≥80%,工具类覆盖率≥100%;
  • 禁止使用过时API(如Date→LocalDateTime);
  • 禁止魔法值,所有常量必须放在constant包;
  • 方法注释必须包含「功能描述/参数说明/返回值说明/异常说明」。

二、父子工程(按职责拆分):中大型项目的可扩展之选

1. 适用场景

  • 核心人群:5人以上团队、跨部门协作场景
  • 项目特征:长期迭代、多业务线并行、需要模块复用与解耦
  • 典型案例:企业级学生管理平台(含学籍、缴费、选课等多条业务线)、SaaS类产品、需持续迭代的商业项目

2. 核心优势

父子工程的核心是"解耦协作、支撑长期发展":

  • 模块边界清晰:按职责拆分为父工程(统一依赖管理、公共配置)+ 子模块(业务模块、公共组件模块、第三方集成模块等),避免单工程后期代码冗余、职责混乱;
  • 协作效率提升:多团队可并行开发不同子模块,通过接口定义实现低耦合协作,减少代码冲突;
  • 复用性强:公共组件(如工具类、统一返回结果、异常处理)可抽离为独立子模块,供所有业务模块复用,降低重复开发成本;
  • 可扩展性强:支持后续业务拆分(如将核心业务模块独立为微服务),为项目长期迭代预留架构空间。

3. 模板参考

以下以学生管理系统为例:

bash 复制代码
student-management-system/                  # 【父工程】仅做依赖版本管控/子模块声明,无任何业务代码
│                                           # 核心规则:1. packaging=pom;2. 仅通过dependencyManagement统一版本;3. 禁止写业务逻辑
├── pom.xml                                 # 父POM核心:
│                                           # - 声明子模块(common/api/data/biz/facade/app)
│                                           # - dependencyManagement管理所有依赖版本(SpringBoot/MP/Redis等)
│                                           # - 统一配置Maven插件(编译/打包/测试)
├── README.md                               # 项目总说明:模块划分、依赖关系、启动/部署流程、运维手册
├── .gitignore                              # 全局Git忽略:IDE配置、编译产物、日志、敏感配置
├── .editorconfig                           # 全局编辑器规范:缩进4空格、编码UTF-8、换行符LF(团队协作无格式冲突)
├── .checkstyle.xml                         # 全局代码校验:对齐阿里Java开发手册,编译强制校验
├── student-common/                         # 【子模块1:通用核心】全项目复用,无业务侵入,所有模块依赖此模块
│                                           # 依赖关系:仅依赖父工程,无其他子模块依赖
│   ├── pom.xml                             # 子POM:
│                                           # - parent继承父工程
│                                           # - 仅引入通用依赖(lombok/validation/jasypt/spring-context)
│                                           # - 禁止引入业务依赖(MyBatis-Plus/MySQL/Redis)
│   └── src/main/java/com/xxx/edu/common/   # 通用核心包(包名统一,可跨项目复用)
│       ├── config/                         # 通用配置(跨模块复用,无业务关联)
│       │   ├── CorsConfig.java             # 跨域配置:生产环境限定前端域名,禁止*(企业级安全)
│       │   ├── TransactionConfig.java      # 事务配置:强制rollbackFor=Exception,保证事务一致性
│       │   ├── MyBatisPlusBaseConfig.java  # MP基础配置:分页/自动填充,不含业务逻辑
│       │   ├── JasyptConfig.java           # 敏感配置加密:数据库密码/Token密钥加密(企业级数据安全)
│       │   └── SecurityBaseConfig.java     # 安全基础配置:Token解析、权限校验基础规则
│       ├── constant/                       # 全局常量(无业务相关,禁止魔法值)
│       │   ├── DateConstant.java           # 日期格式:YYYY-MM-DD HH:mm:ss(统一全项目时间处理)
│       │   ├── RegexConstant.java          # 通用正则:手机号/身份证/邮箱/学号(统一校验规则)
│       │   ├── SecurityConstant.java       # 安全常量:Token过期时间/加密盐值/权限前缀
│       │   └── CacheConstant.java          # 缓存常量:缓存键前缀/过期时间(统一Redis管理)
│       ├── exception/                      # 通用异常体系(全项目复用,分级处理)
│       │   ├── BusinessException.java      # 业务异常:已知错误(如"学号已存在"),用户可感知
│       │   ├── SystemException.java        # 系统异常:未知错误(如DB连接失败),隐藏敏感详情
│       │   ├── AuthException.java          # 认证异常:Token过期/无权限,统一返回401/403
│       │   ├── GlobalExceptionHandler.java # 全局异常处理器:所有模块异常统一返回R<T>,避免前端适配多格式
│       │   └── validation/                 # 自定义通用校验(跨模块复用)
│       │       ├── StudentNo.java          # 学号校验注解:2024开头+8位数字(业务通用规则)
│       │       ├── StudentNoValidator.java # 学号校验器实现:逻辑与注解解耦,便于扩展
│       │       ├── IdCard.java             # 身份证校验注解:18位含校验位(企业级数据合法性)
│       │       └── IdCardValidator.java    # 身份证校验器实现:兼容15/18位身份证
│       ├── interceptor/                    # 通用拦截器(无业务逻辑,前置处理请求)
│       │   ├── TraceIdInterceptor.java     # 全链路TraceId:日志追踪核心,生产问题定位必备
│       │   ├── AuthInterceptor.java        # 认证拦截器:校验Token有效性,公开接口(登录)除外
│       │   ├── DataScopeInterceptor.java   # 数据权限拦截器:按角色过滤数据(如教师仅看本班学生)
│       │   └── OperateLogInterceptor.java  # 操作审计拦截器:记录操作用户/IP/内容/结果(合规审计)
│       ├── aspect/                         # 通用AOP(解耦横切逻辑,跨模块复用)
│       │   ├── OperateLogAspect.java       # 操作日志切面:注解式记录,减少业务代码重复
│       │   ├── CacheAspect.java            # 缓存切面:注解式缓存,提高查询性能,降低DB压力
│       │   └── IdempotentAspect.java       # 幂等性切面:防重复提交(如成绩重复录入),保证数据一致性
│       ├── model/                          # 通用模型(全项目复用,无业务字段)
│       │   ├── R.java                      # 统一返回类:所有接口必须返回此类型,字段固定(code/message/data/traceId/timestamp)
│       │   ├── PageParam.java              # 分页入参:所有分页接口统一(pageNum/pageSize/keyword)
│       │   ├── PageData.java             # 分页出参:所有分页接口统一(list/total/totalPage)
│       │   ├── BasePO.java                 # 审计基类:创建时间/更新时间/创建人/更新人/逻辑删除(企业级数据审计)
│       │   ├── OperateLogPO.java           # 操作日志实体:审计合规必备,记录所有关键操作
│       │   └── DictPO.java                 # 字典实体:系统配置核心(如性别/专业/课程类型)
│       └── util/                           # 通用工具类:私有化构造,禁止实例化,所有方法静态化
│           ├── StringUtil.java             # 字符串工具:脱敏(手机号/身份证)、判空、格式化
│           ├── DateUtil.java               # 日期工具:计算入学/毕业时间、年龄、日期格式化
│           ├── EncryptUtil.java            # 加密工具:密码MD5/AES、Token生成(企业级数据安全)
│           ├── TokenUtil.java              # Token工具:生成/解析/校验JWT Token
│           ├── IpUtil.java                 # IP工具:获取客户端真实IP、IP归属地(审计/风控)
│           └── SecurityUtil.java           # 权限工具:获取当前用户/角色/数据范围(RBAC核心)
├── student-api/                            # 【子模块2:接口契约】前后端/跨模块交互唯一标准,无业务逻辑
│                                           # 依赖关系:仅依赖student-common,无其他子模块依赖
│   ├── pom.xml                             # 子POM:
│                                           # - parent继承父工程
│                                           # - 依赖student-common
│                                           # - 仅引入DTO/VO相关依赖(lombok/validation)
│   └── src/main/java/com/xxx/edu/api/      # 接口契约包(仅定义标准,无实现)
│       ├── dto/                            # DTO:入参/出参,按业务模块拆分,禁止含业务逻辑
│       │   ├── user/                       # 用户模块DTO
│       │   │   ├── req/                    # 入参DTO:前端传入,加校验注解(非空/长度/格式)
│       │   │   │   ├── UserLoginReq.java   # 登录入参:账号/密码/验证码(密码密文传输)
│       │   │   │   ├── UserAddReq.java     # 新增用户入参:账号/姓名/角色ID/用户类型
│       │   │   │   └── UserQueryReq.java   # 用户查询入参:关键词/用户类型/分页参数
│       │   │   └── resp/                   # 出参DTO:返回前端,敏感字段脱敏
│       │   │       ├── UserLoginResp.java  # 登录出参:Token/用户ID/姓名/用户类型(无密码)
│       │   │       └── UserInfoResp.java   # 用户信息出参:姓名/手机号(脱敏)/角色/状态
│       │   ├── student/                    # 学生模块DTO(入参/出参分离)
│       │   ├── clazz/                      # 班级模块DTO
│       │   ├── course/                     # 课程模块DTO
│       │   ├── score/                      # 成绩模块DTO
│       │   └── attendance/                 # 考勤模块DTO
│       ├── vo/                             # VO:前端展示专用,组合多表数据,简化展示
│       │   ├── StudentListItemVO.java      # 学生列表项:学号/姓名/班级/状态(仅展示核心字段,减少传输)
│       │   ├── CourseScoreVO.java          # 课程成绩VO:课程名+分数+等级+排名(组合Score/Course表)
│       │   └── AttendanceStatsVO.java      # 考勤统计VO:学生名+出勤次数+缺勤次数+出勤率(统计结果)
│       ├── enums/                          # 枚举:统一管理状态/类型/错误码,禁止魔法值
│       │   ├── BizErrorCodeEnum.java          # 全局错误码:200成功/4xx客户端错/5xx服务端错/6xx业务错(前后端统一)
│       │   ├── UserTypeEnum.java           # 用户类型:ADMIN/TEACHER/STUDENT/PARENT(RBAC权限核心)
│       │   ├── StudentStatusEnum.java      # 学生状态:NORMAL/LEAVE/GRADUATE/TRANSFER(学籍管理)
│       │   ├── ScoreLevelEnum.java         # 成绩等级:A/B/C/D/F/EXCELLENT(成绩统计)
│       │   └── AttendanceStatusEnum.java   # 考勤状态:PRESENT/ABSENT/LATE/LEAVE(考勤管理)
│       └── feign/                          # Feign客户端:对接外部微服务,预留扩展(如教务/缴费系统)
│           └── EduPayFeignClient.java      # 缴费系统对接:学费/教材费缴纳接口(企业级多系统集成)
├── student-data/                           # 【子模块3:数据访问】仅做CRUD,禁止业务逻辑
│                                           # 依赖关系:依赖student-common + student-api,无其他子模块依赖
│   ├── pom.xml                             # 子POM:
│                                           # - parent继承父工程
│                                           # - 依赖student-common、student-api
│                                           # - 引入MyBatis-Plus、MySQL、druid(数据层专属依赖)
│   └── src/main/java/com/xxx/edu/data/     # 数据访问包(仅数据操作,无业务)
│       ├── mapper/                         # Mapper接口:MP注解/XML,仅数据CRUD
│       │   ├── UserMapper.java             # 用户Mapper:增删改查(含根据账号查询、角色关联查询)
│       │   ├── StudentMapper.java          # 学生Mapper:增删改查+复杂统计(按年级/专业/状态)
│       │   ├── ClazzMapper.java            # 班级Mapper:增删改查(含关联班主任查询)
│       │   ├── CourseMapper.java           # 课程Mapper:增删改查(含关联授课教师查询)
│       │   ├── ScoreMapper.java            # 成绩Mapper:增删改查+统计(班级平均分/年级排名)
│       │   ├── AttendanceMapper.java       # 考勤Mapper:增删改查+统计(月度考勤率/缺勤排名)
│       │   ├── OperateLogMapper.java       # 操作日志Mapper:增删改查(审计日志查询)
│       │   └── DictMapper.java             # 字典Mapper:增删改查(系统配置查询)
│       ├── po/                             # 数据库实体:与表一一对应,继承BasePO(审计字段复用)
│       │   ├── UserPO.java                 # 用户表:id/账号/密码(加密)/姓名/用户类型/角色ID/状态
│       │   ├── StudentPO.java              # 学生表:学号/姓名/性别/身份证(脱敏)/手机号(脱敏)/班级ID/年级/专业/状态
│       │   ├── ClazzPO.java                # 班级表:id/班级编号/年级/专业/班主任ID/创建时间
│       │   ├── CoursePO.java               # 课程表:id/课程编号/课程名/学分/授课教师ID/课时/状态
│       │   ├── ScorePO.java                # 成绩表:id/学生ID/课程ID/分数/等级/录入人/录入时间
│       │   ├── AttendancePO.java           # 考勤表:id/学生ID/课程ID/考勤状态/日期/备注/录入人
│       │   ├── RolePO.java                 # 角色表:id/角色名/权限标识/状态(RBAC核心)
│       │   └── MenuPO.java                 # 菜单表:id/菜单名/权限标识/父ID/排序(权限控制核心)
│       └── manager/                        # 数据管理器:封装复杂SQL/多表关联,解耦Service与Mapper
│           └── StudentDataManager.java     # 学生数据管理器:多表关联查询(学生+班级+课程+成绩),简化Service逻辑
├── student-biz/                            # 【子模块4:业务核心】仅写业务逻辑,禁止数据操作/第三方对接
│                                           # 依赖关系:依赖student-common + student-api + student-data
│   ├── pom.xml                             # 子POM:
│                                           # - parent继承父工程
│                                           # - 依赖student-common、student-api、student-data
│                                           # - 禁止引入启动/第三方依赖(spring-boot-starter-web/Redis/短信)
│   └── src/main/java/com/xxx/edu/biz/      # 业务逻辑包(按业务模块拆分,高内聚)
│       ├── user/                           # 用户模块业务
│       │   ├── UserService.java            # 业务接口:定义能力(登录/新增用户/查询用户/修改密码)
│       │   └── UserServiceImpl.java        # 业务实现:核心逻辑(密码加密/权限校验/账号唯一性/Token生成)
│       ├── student/                        # 学生模块业务
│       │   ├── StudentService.java         # 业务接口:定义能力(新增学生/查询学生/学籍变更/Excel导入导出)
│       │   └── StudentServiceImpl.java     # 业务实现:核心逻辑(学号校验/年级计算/学籍状态变更/数据权限过滤)
│       ├── clazz/                          # 班级模块业务:班级新增/查询/关联班主任/班课管理
│       ├── course/                         # 课程模块业务:课程新增/查询/选课/排课
│       ├── score/                          # 成绩模块业务:成绩录入/统计/排名/等级转换/Excel导出
│       └── attendance/                     # 考勤模块业务:考勤记录/统计/缺勤提醒/月度报表
├── student-facade/                         # 【子模块5:外部对接】解耦业务与第三方,禁止业务逻辑
│                                           # 依赖关系:依赖student-common + student-api
│   ├── pom.xml                             # 子POM:
│                                           # - parent继承父工程
│                                           # - 依赖student-common、student-api
│                                           # - 引入Redis、OSS、短信SDK(第三方对接专属依赖)
│   └── src/main/java/com/xxx/edu/facade/   # 外部对接包(仅对接,无业务逻辑)
│       ├── cache/                          # 缓存对接:Redis,减少DB查询(高性能核心)
│       │   ├── UserCacheService.java       # 用户缓存:Token/用户信息缓存(过期时间30分钟)
│       │   └── StudentCacheService.java    # 学生缓存:常用学生信息缓存(过期时间1小时)
│       ├── file/                           # 文件对接:OSS/本地文件(文件存储核心)
│       │   └── FileService.java            # 文件服务:学生头像/成绩单/考勤表上传下载(支持分片上传)
│       └── third/                          # 第三方对接:短信/邮件/缴费系统(多系统集成)
│           ├── SmsClient.java              # 短信客户端:考勤提醒/成绩通知/密码找回(对接阿里云短信)
│           ├── MailClient.java             # 邮件客户端:成绩单/学籍证明发送(对接企业邮箱)
│           └── PayClient.java              # 缴费客户端:学费/教材费缴纳(对接校园缴费系统)
└── student-app/                            # 【子模块6:启动模块】仅启动类+配置,无业务逻辑
│                                           # 依赖关系:依赖student-common + student-api + student-data + student-biz + student-facade
    ├── pom.xml                             # 子POM:
    │                                       # - parent继承父工程
    │                                       # - 依赖所有业务模块(student-biz + student-facade)
    │                                       # - 引入spring-boot-starter-web(启动专属依赖)
    │                                       # - 配置spring-boot-maven-plugin,打包成可运行JAR
    ├── src/main/java/com/xxx/edu/app/      # 启动包(仅启动类,无业务逻辑)
    │   └── StudentManagementApplication.java # 唯一启动类:
    │                                           # - @SpringBootApplication扫描所有子模块包
    │                                           # - 仅负责启动,禁止添加业务逻辑/非核心@Bean
    └── src/main/resources/                 # 全局资源:所有模块的资源统一存放(便于运维管理)
        ├── config/                         # 环境隔离配置:禁止dev/prod配置混用
        │   ├── application.yml             # 主配置:通用参数(应用名/编码/时区),指定激活环境
        │   ├── application-dev.yml         # 开发环境:本地数据库/DEBUG日志/Redis本地
        │   ├── application-test.yml        # 测试环境:测试库/INFO日志/Redis测试集群
        │   └── application-prod.yml        # 生产环境:生产库/INFO日志/Redis生产集群(密码加密)
        ├── mapper/                         # MyBatis XML:仅存放复杂SQL(简单SQL用MP注解)
        │   ├── StudentMapper.xml           # 学生复杂查询:按年级/专业/状态统计(多条件组合)
        │   ├── ScoreMapper.xml             # 成绩复杂统计:班级平均分/年级排名/各科成绩分布
        │   └── AttendanceMapper.xml        # 考勤复杂统计:月度考勤率/缺勤原因统计
        ├── script/                         # 数据库脚本:版本化管理,便于环境搭建/版本回溯
        │   ├── init/                       # 初始化脚本:建表/初始数据(管理员账号/字典数据)
        │   │   ├── 20240501_init_table.sql # 建表脚本:用户/学生/课程/成绩等核心表
        │   │   ├── 20240501_init_admin.sql # 初始化管理员:账号admin,密码加密(123456→MD5+盐)
        │   │   └── 20240501_init_dict.sql  # 初始化字典:性别/专业/课程类型/考勤状态
        │   ├── ddl/                        # 结构变更脚本:ALTER TABLE(版本化,如新增字段/索引)
        │   │   └── 20240502_add_student_avatar.sql # 学生表新增头像字段
        │   └── dml/                        # 数据变更脚本:INSERT/UPDATE/DELETE(运维操作)
        │       └── 20240504_update_student_grade.sql # 更新2023级学生年级为2024级
        ├── static/                         # 静态资源:Excel模板/前端页面(前后端分离可简化)
        │   ├── excel/                      # Excel模板:学生导入/成绩导出(版本化管理)
        │   │   ├── student_import_template_1.0.0.xlsx
        │   │   └── score_export_template_1.0.0.xlsx
        │   ├── html/                       # 前端静态页面:登录/报表预览/数据导出预览
        │   └── js/                         # 前端JS:表单校验/数据展示/Excel导入导出
        ├── templates/                      # 模板文件:邮件/Excel动态模板
        │   └── mail/                       # 邮件模板:成绩通知/考勤提醒/学籍变更通知
        │       └── score_notice.ftl
        ├── logback.xml                     # 日志配置:含TraceId/环境隔离/敏感信息脱敏/滚动策略(生产级)
        └── banner.txt                      # 启动横幅:企业/学校标识、项目版本、启动时间(企业级规范)

1. 依赖单向性(禁止循环依赖)

bash 复制代码
student-common ← student-api ← student-data ← student-biz ← student-app
                ↓              ↓              ↓
                student-facade ←─────────────┘
  • 所有模块最终都依赖student-common,但student-common不依赖任何模块;
  • 禁止反向依赖(如student-data依赖student-biz),避免循环依赖导致启动失败。

2. 模块职责唯一(禁止跨职责写代码)

模块 核心职责 禁止做的事
student-common 通用能力复用 写业务逻辑、数据操作、第三方对接
student-api 定义接口契约 写业务逻辑、数据操作、第三方对接
student-data 数据CRUD 写业务逻辑、第三方对接、接口定义
student-biz 业务逻辑实现 数据操作(直接调Mapper除外)、第三方对接、接口定义
student-facade 第三方对接 写业务逻辑、数据操作、接口定义
student-app 项目启动+配置管理 写业务逻辑、数据操作、第三方对接

3. 打包部署规则

  • student-app打包成可运行JAR(其他模块打包成普通JAR,供student-app依赖);
  • 生产环境部署仅需上传student-app的JAR包+配置文件(配置文件可外置,便于运维修改)。
相关推荐
红袜子i44 分钟前
解决 Ubuntu 中 apt-get update 因架构配置混乱导致的更新失败问题
linux·ubuntu·架构
专注于大数据技术栈1 小时前
java学习--注解之@Deprecated
java·学习
CoderYanger1 小时前
动态规划算法-斐波那契数列模型:1.第N个泰波那契数
开发语言·算法·leetcode·动态规划·1024程序员节
Xの哲學1 小时前
Linux 分段卸载技术深度剖析
linux·服务器·网络·架构·边缘计算
zore_c1 小时前
【C语言】文件操作详解2(文件的顺序读写操作)
android·c语言·开发语言·数据结构·笔记·算法·缓存
飞梦工作室1 小时前
Spring Boot3 + Milvus2 实战:向量检索应用开发指南
java·spring boot·后端
weixin_462446231 小时前
使用 Python + Tkinter + openpyxl 实现 Excel 文本化转换
开发语言·python·excel
大袁同学1 小时前
【C++完结篇】:深入“次要”但关键的知识腹地
开发语言·数据结构·c++·算法
m0_740043731 小时前
mapState —— Vuex 语法糖
java·前端·javascript·vue.js