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)
- [1. 统一返回类 `core/model/Result.java`](#1. 统一返回类
- [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包+配置文件(配置文件可外置,便于运维修改)。