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

高级特性

**本文引用的文件** - [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:文件服务,含分片上传、预览、清理任务等。
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 进行链路追踪。
  • 扩展点:消息队列、熔断降级、灰度发布等可按需引入。

[本节为补充性内容,不直接分析具体文件]