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.
21 KiB
21 KiB
高级特性
**本文引用的文件** - [CrmAppApplication.java](file://crm-app/src/main/java/com/crm/app/CrmAppApplication.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.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) - [DataScope.java](file://crm-base/src/main/java/com/crm/base/annotation/DataScope.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) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [ScheduledTaskProperties.java](file://crm-base/src/main/java/com/crm/base/config/ScheduledTaskProperties.java) - [MybatisPlusConfig.java](file://crm-base/src/main/java/com/crm/base/config/MybatisPlusConfig.java) - [MetaObjectFillHandler.java](file://crm-base/src/main/java/com/crm/base/config/MetaObjectFillHandler.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [Result.java](file://crm-base/src/main/java/com/crm/base/domain/result/Result.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) - [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) - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeHelper.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeHelper.java) - [DataOwnership.java](file://crm-base/src/main/java/com/crm/base/security/DataOwnership.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [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) - [FileApiImpl.java](file://crm-file/src/main/java/com/crm/file/service/impl/FileApiImpl.java) - [OrphanChunkCleanupTask.java](file://crm-file/src/main/java/com/crm/file/task/OrphanChunkCleanupTask.java) - [SchedulingConfig.java](file://crm-file/src/main/java/com/crm/file/config/SchedulingConfig.java)目录
简介
本指南面向有经验的开发者,围绕本项目的高级特性进行系统化说明,重点包括:
- 自定义注解与AOP切面:以 DataScope 数据权限为例,讲解注解定义、拦截器实现与SQL注入策略。
- 分布式ID生成器:基于 Snowflake 算法的配置与应用,结合 MyBatis-Plus 的自定义ID生成器。
- JWT认证机制:从过滤器到令牌服务的全链路解析。
- 缓存策略:Redis配置与使用建议。
- 消息队列集成:扩展点与最佳实践(概念性说明)。
- 定时任务开发:基于Spring Schedule的任务组织与配置。
- 性能优化与安全编码规范:通用建议与落地方法。
- 监控埋点:统一异常处理、追踪ID等可观测性手段。
项目结构
本项目采用多模块分层架构:
- crm-app:应用启动入口与全局配置。
- crm-auth:认证授权、JWT、数据权限拦截等安全能力。
- crm-base:公共基础能力,包含注解、配置、工具、异常、安全上下文、分布式ID、缓存与定时任务配置等。
- crm-file:文件服务,含分片上传、预览、清理任务等。
graph TB
subgraph "应用层"
APP["crm-app<br/>启动类与全局配置"]
end
subgraph "认证授权"
AUTH["crm-auth<br/>控制器/安全配置/过滤器/服务"]
end
subgraph "基础能力"
BASE["crm-base<br/>注解/配置/工具/异常/安全上下文"]
end
subgraph "文件服务"
FILE["crm-file<br/>文件API/任务/配置"]
end
APP --> AUTH
APP --> BASE
APP --> FILE
AUTH --> BASE
FILE --> BASE
图表来源
- CrmAppApplication.java
- application.yml
章节来源
- CrmAppApplication.java
- application.yml
核心组件
- 自定义注解与AOP:DataScope 注解配合 DataScopeInterceptor 实现数据范围控制,并通过 MyBatis-Plus 的 SQL 注入器动态拼接 WHERE 条件。
- 分布式ID:SnowflakeIdWorker + SnowflakeProperties + CustomIdGenerator 提供高吞吐、无冲突的雪花ID,并接入 MyBatis-Plus ID生成策略。
- JWT认证:JwtAuthenticationFilter 负责请求解析与鉴权,TokenService 负责令牌签发、校验与刷新。
- 缓存:RedisConfig 提供 Redis 客户端与序列化配置,便于在业务中快速接入缓存。
- 定时任务:ScheduledTaskProperties 提供任务开关与表达式配置;crm-file 中的 OrphanChunkCleanupTask 演示了基于 Spring Schedule 的任务实现。
- 可观测性与异常:GlobalExceptionHandlerAdvice 统一异常响应;TraceIdFilter 为每个请求注入追踪ID。
章节来源
- DataScope.java
- DataScopeInterceptor.java
- SnowflakeIdWorker.java
- SnowflakeProperties.java
- CustomIdGenerator.java
- JwtAuthenticationFilter.java
- TokenService.java
- RedisConfig.java
- ScheduledTaskProperties.java
- OrphanChunkCleanupTask.java
- GlobalExceptionHandlerAdvice.java
- TraceIdFilter.java
架构总览
下图展示了认证与数据权限在请求链路中的位置,以及分布式ID与缓存的接入点。
sequenceDiagram
participant Client as "客户端"
participant Filter as "JwtAuthenticationFilter"
participant TokenSvc as "TokenService"
participant Interceptor as "DataScopeInterceptor"
participant MP as "MyBatis-Plus"
participant DB as "数据库"
Client->>Filter : "携带JWT的请求"
Filter->>TokenSvc : "解析并校验令牌"
TokenSvc-->>Filter : "用户上下文"
Filter-->>Client : "放行或拒绝"
Client->>Interceptor : "进入业务方法前"
Interceptor->>MP : "根据DataScope注解注入SQL条件"
MP->>DB : "执行带数据范围的查询"
DB-->>Client : "返回结果"
图表来源
- JwtAuthenticationFilter.java
- TokenService.java
- DataScopeInterceptor.java
- MybatisPlusConfig.java
详细组件分析
自定义注解与AOP:DataScope 数据权限
- 注解定义:DataScope 用于标注需要数据权限控制的接口或方法,支持指定数据范围级别与目标表。
- 拦截器实现:DataScopeInterceptor 在方法执行前读取当前登录用户与权限信息,结合 DataScopeTables 维护的表映射,构造WHERE片段。
- SQL注入:通过 MyBatis-Plus 的 MetaObjectHandler 或 SQL 注入器将数据范围条件动态注入到查询语句中。
- 上下文管理:DataVisibilityContext 保存当前请求的数据可见性范围,供后续逻辑复用。
classDiagram
class DataScope {
+ "注解:声明数据权限范围"
}
class DataScopeInterceptor {
+ "前置拦截:解析注解与上下文"
+ "注入SQL条件"
}
class DataScopeTables {
+ "表名与字段映射"
}
class DataVisibilityContext {
+ "存储当前可见范围"
}
class LoginUser {
+ "用户基本信息"
}
DataScopeInterceptor --> DataScope : "解析注解"
DataScopeInterceptor --> DataScopeTables : "查表映射"
DataScopeInterceptor --> DataVisibilityContext : "设置上下文"
DataScopeInterceptor --> LoginUser : "获取用户信息"
图表来源
- DataScope.java
- DataScopeInterceptor.java
- DataScopeTables.java
- DataVisibilityContext.java
- LoginUser.java
章节来源
- DataScope.java
- DataScopeInterceptor.java
- DataScopeTables.java
- DataVisibilityContext.java
- LoginUser.java
分布式ID生成器:Snowflake 算法
- 算法要点:时间戳+机器ID+序列号,保证全局唯一且有序递增。
- 配置项:SnowflakeProperties 提供数据中心ID、机器ID等参数。
- 工作器:SnowflakeIdWorker 实现核心生成逻辑。
- 集成方式:CustomIdGenerator 作为 MyBatis-Plus 的 ID 生成器,实体继承 BaseEntity 或 OwnedEntity 即可自动填充ID。
flowchart TD
Start(["开始"]) --> LoadCfg["加载SnowflakeProperties"]
LoadCfg --> InitWorker["初始化SnowflakeIdWorker"]
InitWorker --> NeedId{"是否需要新ID?"}
NeedId --> |是| Gen["调用SnowflakeIdWorker生成"]
Gen --> SetField["写入实体ID字段"]
SetField --> End(["结束"])
NeedId --> |否| End
图表来源
- SnowflakeProperties.java
- SnowflakeIdWorker.java
- CustomIdGenerator.java
- BaseEntity.java
- OwnedEntity.java
章节来源
- SnowflakeProperties.java
- SnowflakeIdWorker.java
- CustomIdGenerator.java
- BaseEntity.java
- OwnedEntity.java
JWT认证机制
- 过滤器:JwtAuthenticationFilter 负责从请求头提取JWT,调用 TokenService 校验并构建安全上下文。
- 令牌服务:TokenService 提供签发、校验、刷新与注销能力。
- 安全配置:SecurityConfig 注册过滤器与访问规则。
- 登录流程:AuthController 接收登录参数,验证后返回JWT。
sequenceDiagram
participant C as "客户端"
participant AC as "AuthController"
participant TS as "TokenService"
participant F as "JwtAuthenticationFilter"
C->>AC : "POST /login"
AC->>TS : "签发JWT"
TS-->>AC : "返回令牌"
AC-->>C : "{token}"
C->>F : "携带Authorization : Bearer <token>"
F->>TS : "校验令牌"
TS-->>F : "用户上下文"
F-->>C : "放行至业务"
图表来源
- AuthController.java
- TokenService.java
- JwtAuthenticationFilter.java
- SecurityConfig.java
章节来源
- AuthController.java
- TokenService.java
- JwtAuthenticationFilter.java
- SecurityConfig.java
缓存策略(Redis)
- 配置:RedisConfig 提供 RedisTemplate 与序列化策略,确保对象存取一致性。
- 使用建议:热点数据优先缓存,合理设置过期时间与更新策略(如失效模式或延迟双删),避免穿透与雪崩。
- 典型场景:字典、菜单树、权限信息等读多写少的数据。
flowchart TD
A["业务方法"] --> CheckCache{"缓存命中?"}
CheckCache --> |是| ReturnCache["返回缓存值"]
CheckCache --> |否| QueryDB["查询数据库"]
QueryDB --> UpdateCache["更新缓存"]
UpdateCache --> ReturnDB["返回DB结果"]
图表来源
- RedisConfig.java
章节来源
- RedisConfig.java
消息队列集成(概念性)
- 设计思路:将耗时操作(如通知、报表生成、异步导入)放入消息队列,提升主流程响应速度。
- 推荐方案:RabbitMQ/Kafka,结合重试与死信队列保障可靠性。
- 与现有体系集成:可在 Service 层发布消息,消费者独立部署,解耦业务。
[本节为概念性说明,不直接分析具体文件]
定时任务开发
- 配置:ScheduledTaskProperties 提供任务开关与表达式,便于环境差异化配置。
- 示例:OrphanChunkCleanupTask 演示了清理未完成的分片上传记录。
- 最佳实践:幂等性、失败重试、限流与监控告警。
flowchart TD
Start(["定时触发"]) --> LoadCfg["读取ScheduledTaskProperties"]
LoadCfg --> Exec{"任务启用?"}
Exec --> |是| Run["执行清理逻辑"]
Run --> Log["记录日志与指标"]
Log --> End(["结束"])
Exec --> |否| End
图表来源
- ScheduledTaskProperties.java
- OrphanChunkCleanupTask.java
- SchedulingConfig.java
章节来源
- ScheduledTaskProperties.java
- OrphanChunkCleanupTask.java
- SchedulingConfig.java
依赖分析
- 模块耦合:crm-auth 与 crm-base 强耦合(安全上下文、异常、工具),crm-file 依赖 crm-base 的基础能力。
- 外部依赖:MyBatis-Plus(SQL注入与分页)、Redis(缓存)、Spring Security(可选,按实际使用)、Spring Schedule(定时任务)。
- 潜在风险:注意循环依赖与Bean初始化顺序,尤其是自定义ID生成器与元数据填充处理器。
graph LR
AUTH["crm-auth"] --> BASE["crm-base"]
FILE["crm-file"] --> BASE
APP["crm-app"] --> AUTH
APP --> FILE
APP --> BASE
图表来源
- CrmAppApplication.java
- MybatisPlusConfig.java
- RedisConfig.java
章节来源
- CrmAppApplication.java
- MybatisPlusConfig.java
- RedisConfig.java
性能考虑
- 数据库层面:合理使用索引,避免全表扫描;分页查询限制最大页大小;批量插入/更新减少往返。
- 缓存层面:热点数据优先缓存,设置合理的TTL;对大对象进行压缩或拆分;避免缓存穿透(空值缓存/布隆过滤器)。
- 并发与线程池:区分IO密集型与CPU密集型任务,合理配置线程池大小与队列容量。
- 分布式ID:确保机器ID分配唯一,避免时钟回拨问题;必要时引入容错与补偿机制。
- 网络与序列化:选择高效序列化协议(如JSON紧凑模式或Protobuf),减少Payload体积。
[本节为通用指导,不直接分析具体文件]
故障排查指南
- 统一异常处理:GlobalExceptionHandlerAdvice 捕获业务异常与系统异常,返回标准 Result 结构。
- 常见异常类型:
- BusinessErrorException:业务规则校验失败。
- PermissionErrorException:权限不足。
- ResourceNotExistException:资源不存在。
- 追踪与定位:TraceIdFilter 为每个请求注入 TraceId,便于日志聚合与链路追踪。
- 调试建议:开启详细日志,关注拦截器与过滤器的执行顺序;检查JWT签名与过期时间;核对数据权限表映射是否正确。
章节来源
- GlobalExceptionHandlerAdvice.java
- Result.java
- ResultCodeEnum.java
- BusinessErrorException.java
- PermissionErrorException.java
- ResourceNotExistException.java
- TraceIdFilter.java
结论
本项目在认证授权、数据权限、分布式ID、缓存与定时任务等方面提供了完善的基础能力。通过自定义注解与AOP实现灵活的数据范围控制,借助 Snowflake 算法保障ID唯一性,结合 JWT 与统一异常处理提升安全性与可观测性。建议在业务中遵循统一的编码规范与性能优化策略,持续完善监控与告警,确保系统稳定与可扩展。
[本节为总结性内容,不直接分析具体文件]
附录
- 安全编码规范:输入校验、敏感信息脱敏、SQL注入防护、XSS防护、CSRF防护(按需启用)。
- 监控埋点:关键路径打点(QPS、延迟、错误率),结合 TraceId 进行链路追踪。
- 扩展点:消息队列、熔断降级、灰度发布等可按需引入。
[本节为补充性内容,不直接分析具体文件]