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