You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
28 KiB
28 KiB
基础框架
**本文引用的文件** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [BaseEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/BaseEntity.java) - [OwnedEntity.java](file://crm-base/src/main/java/com/crm/base/domain/entity/OwnedEntity.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.java) - [PageConverter.java](file://crm-base/src/main/java/com/crm/base/utils/PageConverter.java) - [BeanCopyUtils.java](file://crm-base/src/main/java/com/crm/base/utils/BeanCopyUtils.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [CrmSqlInjector.java](file://crm-base/src/main/java/com/crm/base/config/CrmSqlInjector.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [InsertBatchOnDuplicateKeyUpdate.java](file://crm-base/src/main/java/com/crm/base/config/InsertBatchOnDuplicateKeyUpdate.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [SnowflakeIdWorker.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeIdWorker.java) - [SnowflakeProperties.java](file://crm-base/src/main/java/com/crm/base/config/SnowflakeProperties.java) - [CustomIdGenerator.java](file://crm-base/src/main/java/com/crm/base/config/CustomIdGenerator.java) - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) - [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.java) - [PageResult.java](file://crm-base/src/main/java/com/crm/base/domain/result/PageResult.java) - [ResultCodeEnum.java](file://crm-base/src/main/java/com/crm/base/domain/result/ResultCodeEnum.java) - [BusinessErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/BusinessErrorException.java) - [MissingParameterException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/MissingParameterException.java) - [PermissionErrorException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/PermissionErrorException.java) - [ResourceNotExistException.java](file://crm-base/src/main/java/com/crm/base/domain/exception/ResourceNotExistException.java) - [DataOwnership.java](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [SystemController.java](file://crm-auth/src/main/java/com/crm/auth/controller/SystemController.java) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [DataScopeTables.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeTables.java) - [AuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java) - [AuthUserServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthUserServiceImpl.java) - [SysDeptServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/SysDeptServiceImpl.java) - [FileInfoServiceImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileInfoServiceImpl.java) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [MinioConfig.java](file://crm-file/src/main/java/com/crm/file/config/MinioConfig.java)目录
简介
本技术文档面向“基础框架”模块,系统性梳理通用实体、基础服务接口与实现、全局异常处理、分页工具、Bean转换工具等核心能力;并深入说明自定义注解、拦截器、AOP切面、数据可见性控制等高级特性。同时覆盖数据库配置、Redis缓存、雪花算法ID生成、MyBatis Plus扩展等基础设施的用法与配置,提供扩展点与自定义化指导,帮助开发者基于此框架快速构建业务模块。
项目结构
本项目采用多模块组织:
- crm-app:应用启动入口与全局配置
- crm-base:基础能力(实体基类、通用服务、异常、工具、安全上下文、MyBatis/Redis/雪花ID等)
- crm-auth:认证授权与安全相关能力(JWT、权限、数据范围)
- crm-file:文件上传下载与预览集成
graph TB
subgraph "应用层"
APP["crm-app<br/>启动与配置"]
end
subgraph "基础能力"
BASE["crm-base<br/>实体/服务/异常/工具/安全/配置"]
end
subgraph "认证授权"
AUTH["crm-auth<br/>认证/鉴权/数据范围"]
end
subgraph "文件服务"
FILE["crm-file<br/>文件上传/下载/预览"]
end
APP --> BASE
APP --> AUTH
APP --> FILE
AUTH --> BASE
FILE --> BASE
图表来源
- CrmAppApplication.java
- application.yml
章节来源
- CrmAppApplication.java
- application.yml
核心组件
- 通用实体
- BaseEntity:统一主键、创建/更新时间等公共字段
- OwnedEntity:在BaseEntity基础上增加数据归属字段,支撑数据可见性与范围控制
- 基础服务
- IBaseService:定义CRUD、分页、批量操作等通用接口
- BaseServiceImpl:基于MyBatis Plus封装通用实现,减少样板代码
- 全局异常处理
- GlobalExceptionHandlerAdvice:集中捕获业务异常、参数异常、权限异常等,返回统一结果
- 分页与转换
- PageConverter:将查询对象转换为分页请求/响应
- BeanCopyUtils:对象属性拷贝与转换
- 安全与数据可见性
- DataOwnership、DataScope、DataScopeLevel、DataScopeHelper、DataVisibilityContext、LoginUser、SecurityUtils
- 基础设施配置
- MybatisPlusConfig、CrmSqlInjector、MetaObjectFillHandler、InsertBatchOnDuplicateKeyUpdate
- RedisConfig
- SnowflakeIdWorker、SnowflakeProperties、CustomIdGenerator
- 横切能力
- TraceIdFilter:链路追踪ID注入
章节来源
- BaseEntity.java
- OwnedEntity.java
- IBaseService.java
- BaseServiceImpl.java
- GlobalExceptionHandlerAdvice.java
- PageConverter.java
- BeanCopyUtils.java
- DataOwnership.java
- DataScope.java
- DataScopeLevel.java
- DataScopeHelper.java
- DataVisibilityContext.java
- LoginUser.java
- SecurityUtils.java
- MybatisPlusConfig.java
- CrmSqlInjector.java
- MetaObjectFillHandler.java
- InsertBatchOnDuplicateKeyUpdate.java
- RedisConfig.java
- SnowflakeIdWorker.java
- SnowflakeProperties.java
- CustomIdGenerator.java
- TraceIdFilter.java
架构总览
整体分层清晰:控制器层调用服务层,服务层通过MyBatis Plus访问数据库;安全与数据范围通过过滤器、拦截器与AOP切面贯穿;统一结果与异常由全局处理器收敛;Redis用于缓存与分布式场景;雪花算法提供分布式唯一ID。
graph TB
Client["客户端"]
API["控制器层<br/>AuthController/SystemController"]
SVC["服务层<br/>IBaseService + 业务Service"]
MP["MyBatis Plus<br/>Mapper/SQL注入"]
DB["数据库"]
SEC["安全与数据范围<br/>JWT/拦截器/AOP/上下文"]
REDIS["Redis缓存"]
IDG["雪花ID生成器"]
EXC["全局异常处理"]
FILT["TraceId过滤器"]
Client --> API
API --> SVC
SVC --> MP
MP --> DB
API --> SEC
SVC --> SEC
SEC --> REDIS
MP --> IDG
API --> EXC
Client --> FILT --> API
图表来源
- AuthController.java
- SystemController.java
- IBaseService.java
- BaseServiceImpl.java
- MybatisPlusConfig.java
- CrmSqlInjector.java
- RedisConfig.java
- SnowflakeIdWorker.java
- GlobalExceptionHandlerAdvice.java
- TraceIdFilter.java
详细组件分析
通用实体与数据模型
- BaseEntity:提供统一的标识与审计字段,便于所有实体共享公共行为
- OwnedEntity:继承BaseEntity并扩展数据归属字段,配合数据可见性上下文实现行级数据隔离
classDiagram
class BaseEntity {
+id
+createTime
+updateTime
}
class OwnedEntity {
+ownerId
+dataScope
}
OwnedEntity --|> BaseEntity : "继承"
图表来源
- BaseEntity.java
- OwnedEntity.java
章节来源
- BaseEntity.java
- OwnedEntity.java
基础服务接口与实现
- IBaseService:定义标准CRUD、分页、批量插入/更新等接口
- BaseServiceImpl:基于MyBatis Plus封装通用逻辑,减少重复代码,提升一致性
classDiagram
class IBaseService {
+getById(id)
+list(page, query)
+save(entity)
+update(entity)
+deleteById(id)
+batchSave(list)
}
class BaseServiceImpl {
+getById(id)
+list(page, query)
+save(entity)
+update(entity)
+deleteById(id)
+batchSave(list)
}
BaseServiceImpl ..|> IBaseService : "实现"
图表来源
- IBaseService.java
- BaseServiceImpl.java
章节来源
- IBaseService.java
- BaseServiceImpl.java
全局异常处理与统一结果
- GlobalExceptionHandlerAdvice:集中捕获业务异常、参数缺失、权限错误、资源不存在等,统一返回Result
- Result/PageResult/ResultCodeEnum:统一响应结构与状态码
flowchart TD
Start(["请求进入"]) --> Try["执行业务逻辑"]
Try --> Success{"是否成功?"}
Success --> |是| ReturnOK["返回Result.success()"]
Success --> |否| Catch["捕获异常类型"]
Catch --> Map["映射为ResultCodeEnum"]
Map --> Build["构造Result/PageResult"]
Build --> ReturnErr["返回统一错误响应"]
ReturnOK --> End(["结束"])
ReturnErr --> End
图表来源
- GlobalExceptionHandlerAdvice.java
- Result.java
- PageResult.java
- ResultCodeEnum.java
- BusinessErrorException.java
- MissingParameterException.java
- PermissionErrorException.java
- ResourceNotExistException.java
章节来源
- GlobalExceptionHandlerAdvice.java
- Result.java
- PageResult.java
- ResultCodeEnum.java
- BusinessErrorException.java
- MissingParameterException.java
- PermissionErrorException.java
- ResourceNotExistException.java
分页工具与Bean转换
- PageConverter:封装分页参数到查询对象,支持排序、过滤条件
- BeanCopyUtils:简化对象间属性复制与转换,避免手写getter/setter
sequenceDiagram
participant C as "控制器"
participant PC as "PageConverter"
participant S as "服务层"
participant M as "Mapper"
C->>PC : "构建分页查询对象"
PC-->>C : "返回标准化分页参数"
C->>S : "调用分页查询"
S->>M : "执行分页SQL"
M-->>S : "返回分页数据"
S-->>C : "返回PageResult"
图表来源
- PageConverter.java
- BeanCopyUtils.java
章节来源
- PageConverter.java
- BeanCopyUtils.java
自定义注解、拦截器与AOP切面
- DataScope注解:标注方法或类,声明数据范围策略
- DataScopeInterceptor:拦截器解析数据范围,注入到查询上下文
- DataScopeHelper/DataScopeLevel:辅助计算与级别管理
- DataVisibilityContext:线程级数据可见性上下文,保证跨层传递
sequenceDiagram
participant C as "控制器"
participant INT as "DataScopeInterceptor"
participant AOP as "AOP切面(DataScope)"
participant CTX as "DataVisibilityContext"
participant S as "服务层"
C->>INT : "请求进入"
INT->>AOP : "解析@DataScope"
AOP->>CTX : "设置数据范围"
AOP-->>INT : "完成上下文设置"
INT-->>C : "放行请求"
C->>S : "执行业务"
S->>CTX : "读取数据范围"
CTX-->>S : "返回范围条件"
图表来源
- DataScope.java
- DataScopeInterceptor.java
- DataScopeHelper.java
- DataScopeLevel.java
- DataVisibilityContext.java
章节来源
- DataScope.java
- DataScopeInterceptor.java
- DataScopeHelper.java
- DataScopeLevel.java
- DataVisibilityContext.java
安全上下文与登录用户
- LoginUser:承载当前登录用户信息
- SecurityUtils:便捷获取当前用户与权限信息
- DataOwnership:数据所有权标记,结合数据范围实现细粒度控制
classDiagram
class LoginUser {
+userId
+username
+roles
+permissions
}
class SecurityUtils {
+getCurrentUser()
+hasRole(role)
+hasPermission(permission)
}
class DataOwnership {
+ownerId
+scopeLevel
}
SecurityUtils --> LoginUser : "持有"
DataOwnership --> LoginUser : "关联"
图表来源
- LoginUser.java
- SecurityUtils.java
- DataOwnership.java
章节来源
- LoginUser.java
- SecurityUtils.java
- DataOwnership.java
数据库配置与MyBatis Plus扩展
- MybatisPlusConfig:注册插件、分页、乐观锁等扩展
- CrmSqlInjector:自定义SQL注入器,增强查询能力
- MetaObjectFillHandler:自动填充审计字段(如创建时间、更新时间)
- InsertBatchOnDuplicateKeyUpdate:批量插入去重更新策略
flowchart TD
Start(["应用启动"]) --> LoadCfg["加载MybatisPlusConfig"]
LoadCfg --> RegisterPlugins["注册插件(分页/乐观锁)"]
RegisterCfg --> Injector["注册CrmSqlInjector"]
InjectCfg --> FillHandler["注册MetaObjectFillHandler"]
FillHandler --> BatchUpdate["启用批量插入去重更新"]
BatchUpdate --> Ready(["准备就绪"])
图表来源
- MybatisPlusConfig.java
- CrmSqlInjector.java
- MetaObjectFillHandler.java
- InsertBatchOnDuplicateKeyUpdate.java
章节来源
- MybatisPlusConfig.java
- CrmSqlInjector.java
- MetaObjectFillHandler.java
- InsertBatchOnDuplicateKeyUpdate.java
Redis缓存配置
- RedisConfig:序列化、连接池、过期策略等配置项
classDiagram
class RedisConfig {
+redisTemplate
+cacheManager
+setSerializer()
+setExpiration()
}
图表来源
- RedisConfig.java
章节来源
- RedisConfig.java
雪花算法ID生成
- SnowflakeIdWorker:分布式唯一ID生成器
- SnowflakeProperties:工作节点ID等配置
- CustomIdGenerator:与MyBatis Plus集成,作为实体ID生成策略
sequenceDiagram
participant App as "应用"
participant Gen as "CustomIdGenerator"
participant SW as "SnowflakeIdWorker"
App->>Gen : "请求生成ID"
Gen->>SW : "调用雪花算法"
SW-->>Gen : "返回唯一ID"
Gen-->>App : "返回ID"
图表来源
- SnowflakeIdWorker.java
- SnowflakeProperties.java
- CustomIdGenerator.java
章节来源
- SnowflakeIdWorker.java
- SnowflakeProperties.java
- CustomIdGenerator.java
认证与授权流程(JWT)
- JwtAuthenticationFilter:解析JWT并设置安全上下文
- TokenService:令牌签发与校验
- SecurityConfig:安全配置与路径白名单
sequenceDiagram
participant Client as "客户端"
participant Filter as "JwtAuthenticationFilter"
participant Token as "TokenService"
participant Sec as "SecurityConfig"
Client->>Filter : "携带Authorization头"
Filter->>Token : "解析并验证Token"
Token-->>Filter : "返回用户信息"
Filter->>Sec : "设置SecurityContext"
Sec-->>Client : "放行至控制器"
图表来源
- JwtAuthenticationFilter.java
- TokenService.java
- SecurityConfig.java
章节来源
- JwtAuthenticationFilter.java
- TokenService.java
- SecurityConfig.java
文件服务集成(示例)
- FileApiImpl:文件API实现,对接存储与预览服务
- FileInfoServiceImpl:文件元数据管理与持久化
- MinioConfig:MinIO客户端配置
classDiagram
class FileApiImpl {
+upload(file)
+download(fileId)
+preview(fileId)
}
class FileInfoServiceImpl {
+save(info)
+getById(id)
+deleteById(id)
}
class MinioConfig {
+endpoint
+accessKey
+secretKey
+bucketName
}
FileApiImpl --> FileInfoServiceImpl : "使用"
FileApiImpl --> MinioConfig : "配置"
图表来源
- FileApiImpl.java
- FileInfoServiceImpl.java
- MinioConfig.java
章节来源
- FileApiImpl.java
- FileInfoServiceImpl.java
- MinioConfig.java
依赖关系分析
- 模块依赖
- crm-app依赖crm-base、crm-auth、crm-file
- crm-auth依赖crm-base(安全上下文、异常、工具)
- crm-file依赖crm-base(通用实体、工具、配置)
- 内部依赖
- 服务层依赖MyBatis Plus与Redis
- 安全层依赖JWT与上下文
- 基础设施层提供ID生成、序列化、填充策略
graph LR
APP["crm-app"] --> BASE["crm-base"]
APP --> AUTH["crm-auth"]
APP --> FILE["crm-file"]
AUTH --> BASE
FILE --> BASE
BASE --> DB["数据库"]
BASE --> REDIS["Redis"]
图表来源
- CrmAppApplication.java
- application.yml
章节来源
- CrmAppApplication.java
- application.yml
性能考虑
- 分页查询:合理设置页大小,避免大结果集一次性加载
- 批量操作:使用批量插入/更新减少往返次数
- 缓存策略:热点数据使用Redis缓存,注意过期与一致性
- ID生成:雪花算法无锁且有序,适合高并发场景
- SQL优化:借助CrmSqlInjector与MyBatis Plus插件,避免N+1问题
[本节为通用建议,不直接分析具体文件]
故障排查指南
- 统一异常分类:业务异常、参数缺失、权限错误、资源不存在
- 日志与追踪:TraceIdFilter注入链路ID,便于定位问题
- 常见错误
- 权限不足:检查SecurityContext与角色/权限配置
- 数据范围异常:确认@DataScope与上下文是否正确设置
- 缓存异常:检查Redis连接与序列化配置
- ID冲突:确认雪花工作节点ID配置唯一
章节来源
- GlobalExceptionHandlerAdvice.java
- TraceIdFilter.java
- RedisConfig.java
- SnowflakeProperties.java
结论
本基础框架以清晰的模块化设计、统一的实体与服务抽象、完善的安全与数据范围控制、强大的基础设施配置为核心,提供了开箱即用的开发体验。通过扩展点与自定义化指导,开发者可快速搭建稳定、高性能的业务模块。
[本节为总结性内容,不直接分析具体文件]
附录
- 扩展点建议
- 自定义数据范围策略:扩展DataScopeHelper与DataScopeLevel
- 新增异常类型:在GlobalExceptionHandlerAdvice中统一处理
- 扩展MyBatis插件:在MybatisPlusConfig中注册
- 自定义ID生成:替换CustomIdGenerator实现
- 常用配置项
- 数据库连接、Redis连接、雪花工作节点ID、MinIO端点等
[本节为补充信息,不直接分析具体文件]