xtools-boot一款基于JDK25,SpringBoot4的通用Spring工具库
xtools-boot 项目设计文档 开源地址: https://gitee.com/jun-xtools/xtools-boot.git 一、功能和用途 1.1 项目概述 项目信息 描述 项目名称 xtools-boot 项目版本 5.0.0 父POM xtools-parent-boot:5.0.0 顶级父POM xtools-parent:5.0.0 Spring Boot 4.0.6 JDK版本 25 项目定位 SpringBoot工具模块框架,为业务应用提供开箱即用的基础能力 维护团队 org.xujun 1.2 技术特点 采用最新的 JDK 25 版本,充分利用虚拟线程(Virtual Threads)、ScopedValue等新特性 基于 Spring Boot 4.0.6 构建,支持自动配置和快速开发 使用 MyBatis-Plus 3.5.16 简化数据访问层开发 使用 MyBatis 4.0.1 提供灵活的SQL映射能力 使用 Druid 1.2.28 数据库连接池,内置SQL监控 集成 Elasticsearch 9.2.8 实现日志存储和检索 支持 Knife4j 4.5.0 自动生成 API 文档 集成 Spring AMQP 4.0.3 实现 RabbitMQ 异步消息处理 集成 Spring Data Redis 实现分布式缓存 集成 XXL-JOB 3.4.0 实现分布式任务调度 集成 Spring Boot Admin 4.0.4 实现应用监控 使用 Jackson 3.1.2 进行 JSON 序列化/反序列化 使用 FastJSON2 2.0.60 处理JSON数据 使用 Lombok 1.18.46 简化Java代码 使用 MapStruct 1.6.3 进行对象映射转换 支持 S3 2.42.41 对象存储 使用 ip2region 3.3.7 实现IP地址定位 1.3 核心功能 #mq6cnds9fgbtdm061ep{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cnds9fgbtdm061ep .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cnds9fgbtdm061ep .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cnds9fgbtdm061ep .error-icon{fill:#a44141;}#mq6cnds9fgbtdm061ep .error-text{fill:#ddd;stroke:#ddd;}#mq6cnds9fgbtdm061ep .edge-thickness-normal{stroke-width:1px;}#mq6cnds9fgbtdm061ep .edge-thickness-thick{stroke-width:3.5px;}#mq6cnds9fgbtdm061ep .edge-pattern-solid{stroke-dasharray:0;}#mq6cnds9fgbtdm061ep .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cnds9fgbtdm061ep .edge-pattern-dashed{stroke-dasharray:3;}#mq6cnds9fgbtdm061ep .edge-pattern-dotted{stroke-dasharray:2;}#mq6cnds9fgbtdm061ep .marker{fill:lightgrey;stroke:lightgrey;}#mq6cnds9fgbtdm061ep .marker.cross{stroke:lightgrey;}#mq6cnds9fgbtdm061ep svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cnds9fgbtdm061ep p{margin:0;}#mq6cnds9fgbtdm061ep .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cnds9fgbtdm061ep .cluster-label text{fill:#F9FFFE;}#mq6cnds9fgbtdm061ep .cluster-label span{color:#F9FFFE;}#mq6cnds9fgbtdm061ep .cluster-label span p{background-color:transparent;}#mq6cnds9fgbtdm061ep .label text,#mq6cnds9fgbtdm061ep span{fill:#ccc;color:#ccc;}#mq6cnds9fgbtdm061ep .node rect,#mq6cnds9fgbtdm061ep .node circle,#mq6cnds9fgbtdm061ep .node ellipse,#mq6cnds9fgbtdm061ep .node polygon,#mq6cnds9fgbtdm061ep .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cnds9fgbtdm061ep .rough-node .label text,#mq6cnds9fgbtdm061ep .node .label text,#mq6cnds9fgbtdm061ep .image-shape .label,#mq6cnds9fgbtdm061ep .icon-shape .label{text-anchor:middle;}#mq6cnds9fgbtdm061ep .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cnds9fgbtdm061ep .rough-node .label,#mq6cnds9fgbtdm061ep .node .label,#mq6cnds9fgbtdm061ep .image-shape .label,#mq6cnds9fgbtdm061ep .icon-shape .label{text-align:center;}#mq6cnds9fgbtdm061ep .node.clickable{cursor:pointer;}#mq6cnds9fgbtdm061ep .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cnds9fgbtdm061ep .arrowheadPath{fill:lightgrey;}#mq6cnds9fgbtdm061ep .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cnds9fgbtdm061ep .flowchart-link{stroke:lightgrey;fill:none;}#mq6cnds9fgbtdm061ep .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cnds9fgbtdm061ep .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cnds9fgbtdm061ep .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cnds9fgbtdm061ep .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cnds9fgbtdm061ep .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cnds9fgbtdm061ep .cluster text{fill:#F9FFFE;}#mq6cnds9fgbtdm061ep .cluster span{color:#F9FFFE;}#mq6cnds9fgbtdm061ep div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cnds9fgbtdm061ep .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cnds9fgbtdm061ep rect.text{fill:none;stroke-width:0;}#mq6cnds9fgbtdm061ep .icon-shape,#mq6cnds9fgbtdm061ep .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cnds9fgbtdm061ep .icon-shape p,#mq6cnds9fgbtdm061ep .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cnds9fgbtdm061ep .icon-shape rect,#mq6cnds9fgbtdm061ep .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cnds9fgbtdm061ep .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cnds9fgbtdm061ep .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cnds9fgbtdm061ep :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}核心模块Spring上下文工具路径匹配工具枚举工具时间工具树形工具JAR工具Knife4j模块API文档增强白名单配置IP模块IP地址查询IP定位工具脱敏模块数据脱敏注解脱敏类型枚举自定义脱敏线程模块虚拟线程工具异步回调存储模块存储抽象接口文件存储S3存储任务模块任务总线TaskBus任务状态管理XXL-JOB集成日志模块日志总线LogBus日志追踪虚拟线程日志运行信息消息队列模块消息总线MqBusRabbitMQ实现消息编解码错误处理搜索引擎模块ES查询工具ES监控索引操作数据库模块MyBatis配置MyBatis-Plus增强Druid连接池SQL监控拦截MySQL监控缓存模块Redis服务分布式锁缓存监控Hash操作Web模块全局异常处理日志追踪FilterJackson定制配置过滤器链白名单机制API模块统一响应Result异常体系基础枚举日志追踪LogTrack分页模型树形模型XSS过滤注解1.4 功能层次结构 #mq6cndsgg2bh1g5l5s9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgg2bh1g5l5s9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgg2bh1g5l5s9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgg2bh1g5l5s9 .error-icon{fill:#a44141;}#mq6cndsgg2bh1g5l5s9 .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgg2bh1g5l5s9 .edge-thickness-normal{stroke-width:1px;}#mq6cndsgg2bh1g5l5s9 .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgg2bh1g5l5s9 .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgg2bh1g5l5s9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgg2bh1g5l5s9 .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgg2bh1g5l5s9 .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgg2bh1g5l5s9 .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgg2bh1g5l5s9 .marker.cross{stroke:lightgrey;}#mq6cndsgg2bh1g5l5s9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgg2bh1g5l5s9 p{margin:0;}#mq6cndsgg2bh1g5l5s9 .edge{stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .section--1 rect,#mq6cndsgg2bh1g5l5s9 .section--1 path,#mq6cndsgg2bh1g5l5s9 .section--1 circle,#mq6cndsgg2bh1g5l5s9 .section--1 polygon,#mq6cndsgg2bh1g5l5s9 .section--1 path{fill:#1f2020;}#mq6cndsgg2bh1g5l5s9 .section--1 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon--1{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge--1{stroke:#1f2020;}#mq6cndsgg2bh1g5l5s9 .edge-depth--1{stroke-width:17;}#mq6cndsgg2bh1g5l5s9 .section--1 line{stroke:#e0dfdf;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-0 rect,#mq6cndsgg2bh1g5l5s9 .section-0 path,#mq6cndsgg2bh1g5l5s9 .section-0 circle,#mq6cndsgg2bh1g5l5s9 .section-0 polygon,#mq6cndsgg2bh1g5l5s9 .section-0 path{fill:#0b0000;}#mq6cndsgg2bh1g5l5s9 .section-0 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-0{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-0{stroke:#0b0000;}#mq6cndsgg2bh1g5l5s9 .edge-depth-0{stroke-width:14;}#mq6cndsgg2bh1g5l5s9 .section-0 line{stroke:#f4ffff;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-1 rect,#mq6cndsgg2bh1g5l5s9 .section-1 path,#mq6cndsgg2bh1g5l5s9 .section-1 circle,#mq6cndsgg2bh1g5l5s9 .section-1 polygon,#mq6cndsgg2bh1g5l5s9 .section-1 path{fill:#4d1037;}#mq6cndsgg2bh1g5l5s9 .section-1 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-1{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-1{stroke:#4d1037;}#mq6cndsgg2bh1g5l5s9 .edge-depth-1{stroke-width:11;}#mq6cndsgg2bh1g5l5s9 .section-1 line{stroke:#b2efc8;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-2 rect,#mq6cndsgg2bh1g5l5s9 .section-2 path,#mq6cndsgg2bh1g5l5s9 .section-2 circle,#mq6cndsgg2bh1g5l5s9 .section-2 polygon,#mq6cndsgg2bh1g5l5s9 .section-2 path{fill:#3f5258;}#mq6cndsgg2bh1g5l5s9 .section-2 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-2{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-2{stroke:#3f5258;}#mq6cndsgg2bh1g5l5s9 .edge-depth-2{stroke-width:8;}#mq6cndsgg2bh1g5l5s9 .section-2 line{stroke:#c0ada7;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-3 rect,#mq6cndsgg2bh1g5l5s9 .section-3 path,#mq6cndsgg2bh1g5l5s9 .section-3 circle,#mq6cndsgg2bh1g5l5s9 .section-3 polygon,#mq6cndsgg2bh1g5l5s9 .section-3 path{fill:#4f2f1b;}#mq6cndsgg2bh1g5l5s9 .section-3 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-3{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-3{stroke:#4f2f1b;}#mq6cndsgg2bh1g5l5s9 .edge-depth-3{stroke-width:5;}#mq6cndsgg2bh1g5l5s9 .section-3 line{stroke:#b0d0e4;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-4 rect,#mq6cndsgg2bh1g5l5s9 .section-4 path,#mq6cndsgg2bh1g5l5s9 .section-4 circle,#mq6cndsgg2bh1g5l5s9 .section-4 polygon,#mq6cndsgg2bh1g5l5s9 .section-4 path{fill:#6e0a0a;}#mq6cndsgg2bh1g5l5s9 .section-4 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-4{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-4{stroke:#6e0a0a;}#mq6cndsgg2bh1g5l5s9 .edge-depth-4{stroke-width:2;}#mq6cndsgg2bh1g5l5s9 .section-4 line{stroke:#91f5f5;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-5 rect,#mq6cndsgg2bh1g5l5s9 .section-5 path,#mq6cndsgg2bh1g5l5s9 .section-5 circle,#mq6cndsgg2bh1g5l5s9 .section-5 polygon,#mq6cndsgg2bh1g5l5s9 .section-5 path{fill:#3b0048;}#mq6cndsgg2bh1g5l5s9 .section-5 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-5{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-5{stroke:#3b0048;}#mq6cndsgg2bh1g5l5s9 .edge-depth-5{stroke-width:-1;}#mq6cndsgg2bh1g5l5s9 .section-5 line{stroke:#c4ffb7;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-6 rect,#mq6cndsgg2bh1g5l5s9 .section-6 path,#mq6cndsgg2bh1g5l5s9 .section-6 circle,#mq6cndsgg2bh1g5l5s9 .section-6 polygon,#mq6cndsgg2bh1g5l5s9 .section-6 path{fill:#995a01;}#mq6cndsgg2bh1g5l5s9 .section-6 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-6{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-6{stroke:#995a01;}#mq6cndsgg2bh1g5l5s9 .edge-depth-6{stroke-width:-4;}#mq6cndsgg2bh1g5l5s9 .section-6 line{stroke:#66a5fe;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-7 rect,#mq6cndsgg2bh1g5l5s9 .section-7 path,#mq6cndsgg2bh1g5l5s9 .section-7 circle,#mq6cndsgg2bh1g5l5s9 .section-7 polygon,#mq6cndsgg2bh1g5l5s9 .section-7 path{fill:#154706;}#mq6cndsgg2bh1g5l5s9 .section-7 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-7{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-7{stroke:#154706;}#mq6cndsgg2bh1g5l5s9 .edge-depth-7{stroke-width:-7;}#mq6cndsgg2bh1g5l5s9 .section-7 line{stroke:#eab8f9;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-8 rect,#mq6cndsgg2bh1g5l5s9 .section-8 path,#mq6cndsgg2bh1g5l5s9 .section-8 circle,#mq6cndsgg2bh1g5l5s9 .section-8 polygon,#mq6cndsgg2bh1g5l5s9 .section-8 path{fill:#161722;}#mq6cndsgg2bh1g5l5s9 .section-8 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-8{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-8{stroke:#161722;}#mq6cndsgg2bh1g5l5s9 .edge-depth-8{stroke-width:-10;}#mq6cndsgg2bh1g5l5s9 .section-8 line{stroke:#e9e8dd;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-9 rect,#mq6cndsgg2bh1g5l5s9 .section-9 path,#mq6cndsgg2bh1g5l5s9 .section-9 circle,#mq6cndsgg2bh1g5l5s9 .section-9 polygon,#mq6cndsgg2bh1g5l5s9 .section-9 path{fill:#00296f;}#mq6cndsgg2bh1g5l5s9 .section-9 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-9{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-9{stroke:#00296f;}#mq6cndsgg2bh1g5l5s9 .edge-depth-9{stroke-width:-13;}#mq6cndsgg2bh1g5l5s9 .section-9 line{stroke:#ffd690;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-10 rect,#mq6cndsgg2bh1g5l5s9 .section-10 path,#mq6cndsgg2bh1g5l5s9 .section-10 circle,#mq6cndsgg2bh1g5l5s9 .section-10 polygon,#mq6cndsgg2bh1g5l5s9 .section-10 path{fill:#01629c;}#mq6cndsgg2bh1g5l5s9 .section-10 text{fill:lightgrey;}#mq6cndsgg2bh1g5l5s9 .node-icon-10{font-size:40px;color:lightgrey;}#mq6cndsgg2bh1g5l5s9 .section-edge-10{stroke:#01629c;}#mq6cndsgg2bh1g5l5s9 .edge-depth-10{stroke-width:-16;}#mq6cndsgg2bh1g5l5s9 .section-10 line{stroke:#fe9d63;stroke-width:3;}#mq6cndsgg2bh1g5l5s9 .disabled,#mq6cndsgg2bh1g5l5s9 .disabled circle,#mq6cndsgg2bh1g5l5s9 .disabled text{fill:lightgray;}#mq6cndsgg2bh1g5l5s9 .disabled text{fill:#efefef;}#mq6cndsgg2bh1g5l5s9 .section-root rect,#mq6cndsgg2bh1g5l5s9 .section-root path,#mq6cndsgg2bh1g5l5s9 .section-root circle,#mq6cndsgg2bh1g5l5s9 .section-root polygon{fill:hsl(180, 1.5873015873%, 48.3529411765%);}#mq6cndsgg2bh1g5l5s9 .section-root text{fill:#2c2c2c;}#mq6cndsgg2bh1g5l5s9 .section-root span{color:#2c2c2c;}#mq6cndsgg2bh1g5l5s9 .section-2 span{color:#2c2c2c;}#mq6cndsgg2bh1g5l5s9 .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mq6cndsgg2bh1g5l5s9 .edge{fill:none;}#mq6cndsgg2bh1g5l5s9 .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mq6cndsgg2bh1g5l5s9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}xtools-bootSpringBoot工具模块框架API基础统一响应Result异常体系基础枚举日志追踪LogTrack分页模型树形模型Web基础全局异常处理日志追踪FilterJackson定制XSS过滤过滤器链缓存Redis服务分布式锁Hash操作缓存监控数据库MyBatis配置MyBatis-Plus增强Druid连接池SQL监控MySQL监控搜索引擎ES查询工具ES监控消息队列消息总线RabbitMQ实现消息编解码日志日志总线LogBus日志追踪虚拟线程日志任务任务总线TaskBusXXL-JOB集成存储存储抽象接口文件存储S3存储安全数据脱敏XSS防护工具虚拟线程IP定位枚举工具树形工具时间工具1.5 功能关系图 #mq6cndsg08vqsd6i2dvj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsg08vqsd6i2dvj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsg08vqsd6i2dvj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsg08vqsd6i2dvj .error-icon{fill:#a44141;}#mq6cndsg08vqsd6i2dvj .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsg08vqsd6i2dvj .edge-thickness-normal{stroke-width:1px;}#mq6cndsg08vqsd6i2dvj .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsg08vqsd6i2dvj .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsg08vqsd6i2dvj .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsg08vqsd6i2dvj .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsg08vqsd6i2dvj .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsg08vqsd6i2dvj .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsg08vqsd6i2dvj .marker.cross{stroke:lightgrey;}#mq6cndsg08vqsd6i2dvj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsg08vqsd6i2dvj p{margin:0;}#mq6cndsg08vqsd6i2dvj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsg08vqsd6i2dvj .cluster-label text{fill:#F9FFFE;}#mq6cndsg08vqsd6i2dvj .cluster-label span{color:#F9FFFE;}#mq6cndsg08vqsd6i2dvj .cluster-label span p{background-color:transparent;}#mq6cndsg08vqsd6i2dvj .label text,#mq6cndsg08vqsd6i2dvj span{fill:#ccc;color:#ccc;}#mq6cndsg08vqsd6i2dvj .node rect,#mq6cndsg08vqsd6i2dvj .node circle,#mq6cndsg08vqsd6i2dvj .node ellipse,#mq6cndsg08vqsd6i2dvj .node polygon,#mq6cndsg08vqsd6i2dvj .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsg08vqsd6i2dvj .rough-node .label text,#mq6cndsg08vqsd6i2dvj .node .label text,#mq6cndsg08vqsd6i2dvj .image-shape .label,#mq6cndsg08vqsd6i2dvj .icon-shape .label{text-anchor:middle;}#mq6cndsg08vqsd6i2dvj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsg08vqsd6i2dvj .rough-node .label,#mq6cndsg08vqsd6i2dvj .node .label,#mq6cndsg08vqsd6i2dvj .image-shape .label,#mq6cndsg08vqsd6i2dvj .icon-shape .label{text-align:center;}#mq6cndsg08vqsd6i2dvj .node.clickable{cursor:pointer;}#mq6cndsg08vqsd6i2dvj .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsg08vqsd6i2dvj .arrowheadPath{fill:lightgrey;}#mq6cndsg08vqsd6i2dvj .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsg08vqsd6i2dvj .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsg08vqsd6i2dvj .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsg08vqsd6i2dvj .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsg08vqsd6i2dvj .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsg08vqsd6i2dvj .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsg08vqsd6i2dvj .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsg08vqsd6i2dvj .cluster text{fill:#F9FFFE;}#mq6cndsg08vqsd6i2dvj .cluster span{color:#F9FFFE;}#mq6cndsg08vqsd6i2dvj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsg08vqsd6i2dvj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsg08vqsd6i2dvj rect.text{fill:none;stroke-width:0;}#mq6cndsg08vqsd6i2dvj .icon-shape,#mq6cndsg08vqsd6i2dvj .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsg08vqsd6i2dvj .icon-shape p,#mq6cndsg08vqsd6i2dvj .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsg08vqsd6i2dvj .icon-shape rect,#mq6cndsg08vqsd6i2dvj .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsg08vqsd6i2dvj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsg08vqsd6i2dvj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsg08vqsd6i2dvj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}异常异步异步存储持久化序列化HTTP请求过滤器链日志追踪Filter公共FilterController层Service层全局异常处理器Redis缓存数据库消息队列日志总线Elasticsearch任务总线XXL-JOB存储服务本地文件S3对象存储脱敏注解Jackson二、项目结构设计 2.1 整体架构 #mq6cndsgzw8sf9bekbj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgzw8sf9bekbj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgzw8sf9bekbj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgzw8sf9bekbj .error-icon{fill:#a44141;}#mq6cndsgzw8sf9bekbj .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgzw8sf9bekbj .edge-thickness-normal{stroke-width:1px;}#mq6cndsgzw8sf9bekbj .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgzw8sf9bekbj .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgzw8sf9bekbj .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgzw8sf9bekbj .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgzw8sf9bekbj .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgzw8sf9bekbj .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgzw8sf9bekbj .marker.cross{stroke:lightgrey;}#mq6cndsgzw8sf9bekbj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgzw8sf9bekbj p{margin:0;}#mq6cndsgzw8sf9bekbj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgzw8sf9bekbj .cluster-label text{fill:#F9FFFE;}#mq6cndsgzw8sf9bekbj .cluster-label span{color:#F9FFFE;}#mq6cndsgzw8sf9bekbj .cluster-label span p{background-color:transparent;}#mq6cndsgzw8sf9bekbj .label text,#mq6cndsgzw8sf9bekbj span{fill:#ccc;color:#ccc;}#mq6cndsgzw8sf9bekbj .node rect,#mq6cndsgzw8sf9bekbj .node circle,#mq6cndsgzw8sf9bekbj .node ellipse,#mq6cndsgzw8sf9bekbj .node polygon,#mq6cndsgzw8sf9bekbj .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgzw8sf9bekbj .rough-node .label text,#mq6cndsgzw8sf9bekbj .node .label text,#mq6cndsgzw8sf9bekbj .image-shape .label,#mq6cndsgzw8sf9bekbj .icon-shape .label{text-anchor:middle;}#mq6cndsgzw8sf9bekbj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgzw8sf9bekbj .rough-node .label,#mq6cndsgzw8sf9bekbj .node .label,#mq6cndsgzw8sf9bekbj .image-shape .label,#mq6cndsgzw8sf9bekbj .icon-shape .label{text-align:center;}#mq6cndsgzw8sf9bekbj .node.clickable{cursor:pointer;}#mq6cndsgzw8sf9bekbj .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgzw8sf9bekbj .arrowheadPath{fill:lightgrey;}#mq6cndsgzw8sf9bekbj .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgzw8sf9bekbj .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgzw8sf9bekbj .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgzw8sf9bekbj .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgzw8sf9bekbj .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgzw8sf9bekbj .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgzw8sf9bekbj .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgzw8sf9bekbj .cluster text{fill:#F9FFFE;}#mq6cndsgzw8sf9bekbj .cluster span{color:#F9FFFE;}#mq6cndsgzw8sf9bekbj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgzw8sf9bekbj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgzw8sf9bekbj rect.text{fill:none;stroke-width:0;}#mq6cndsgzw8sf9bekbj .icon-shape,#mq6cndsgzw8sf9bekbj .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgzw8sf9bekbj .icon-shape p,#mq6cndsgzw8sf9bekbj .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgzw8sf9bekbj .icon-shape rect,#mq6cndsgzw8sf9bekbj .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgzw8sf9bekbj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgzw8sf9bekbj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgzw8sf9bekbj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}xtools-boot父模块xtools-boot-apiAPI基础模块xtools-boot-core核心工具模块xtools-boot-cache缓存模块xtools-boot-db数据库模块xtools-boot-elasticsearch搜索引擎模块xtools-boot-ipIP工具模块xtools-boot-job任务调度模块xtools-boot-knife4jAPI文档模块xtools-boot-log日志模块xtools-boot-mask脱敏模块xtools-boot-mq消息队列模块xtools-boot-storage存储模块xtools-boot-task任务总线模块xtools-boot-thread线程模块xtools-boot-webWeb基础模块xtools-boot-cache-redisRedis缓存xtools-boot-db-mybatisMyBatisxtools-boot-db-mybatis-plusMyBatis-Plusxtools-boot-job-xxlXXL-JOBxtools-boot-mq-baseMQ基础xtools-boot-mq-rabbitRabbitMQxtools-boot-storage-base存储基础xtools-boot-storage-file文件存储xtools-boot-storage-s3S3存储xtools-boot-web-baseWeb基础xtools-boot-web-filter过滤器2.2 分层架构 #mq6cndsgcslslungmzh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgcslslungmzh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgcslslungmzh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgcslslungmzh .error-icon{fill:#a44141;}#mq6cndsgcslslungmzh .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgcslslungmzh .edge-thickness-normal{stroke-width:1px;}#mq6cndsgcslslungmzh .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgcslslungmzh .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgcslslungmzh .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgcslslungmzh .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgcslslungmzh .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgcslslungmzh .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgcslslungmzh .marker.cross{stroke:lightgrey;}#mq6cndsgcslslungmzh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgcslslungmzh p{margin:0;}#mq6cndsgcslslungmzh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgcslslungmzh .cluster-label text{fill:#F9FFFE;}#mq6cndsgcslslungmzh .cluster-label span{color:#F9FFFE;}#mq6cndsgcslslungmzh .cluster-label span p{background-color:transparent;}#mq6cndsgcslslungmzh .label text,#mq6cndsgcslslungmzh span{fill:#ccc;color:#ccc;}#mq6cndsgcslslungmzh .node rect,#mq6cndsgcslslungmzh .node circle,#mq6cndsgcslslungmzh .node ellipse,#mq6cndsgcslslungmzh .node polygon,#mq6cndsgcslslungmzh .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgcslslungmzh .rough-node .label text,#mq6cndsgcslslungmzh .node .label text,#mq6cndsgcslslungmzh .image-shape .label,#mq6cndsgcslslungmzh .icon-shape .label{text-anchor:middle;}#mq6cndsgcslslungmzh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgcslslungmzh .rough-node .label,#mq6cndsgcslslungmzh .node .label,#mq6cndsgcslslungmzh .image-shape .label,#mq6cndsgcslslungmzh .icon-shape .label{text-align:center;}#mq6cndsgcslslungmzh .node.clickable{cursor:pointer;}#mq6cndsgcslslungmzh .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgcslslungmzh .arrowheadPath{fill:lightgrey;}#mq6cndsgcslslungmzh .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgcslslungmzh .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgcslslungmzh .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgcslslungmzh .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgcslslungmzh .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgcslslungmzh .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgcslslungmzh .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgcslslungmzh .cluster text{fill:#F9FFFE;}#mq6cndsgcslslungmzh .cluster span{color:#F9FFFE;}#mq6cndsgcslslungmzh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgcslslungmzh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgcslslungmzh rect.text{fill:none;stroke-width:0;}#mq6cndsgcslslungmzh .icon-shape,#mq6cndsgcslslungmzh .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgcslslungmzh .icon-shape p,#mq6cndsgcslslungmzh .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgcslslungmzh .icon-shape rect,#mq6cndsgcslslungmzh .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgcslslungmzh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgcslslungmzh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgcslslungmzh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}数据层业务模块层Web层过滤器层SkipFilter白名单过滤器 Order:0LogTrackFilter日志追踪过滤器 Order:100CommonFilter公共过滤器 Order:101GlobalControllerExceptionHandler全局异常处理JacksonConfigJSON序列化配置MvcConverterConfigMVC转换器配置缓存模块 RedisService日志模块 LogBus任务模块 TaskBus消息模块 MqBus存储模块 StorageService脱敏模块 MaskSerializerMyBatis / MyBatis-PlusRedisElasticsearchRabbitMQ文件系统 / S32.3 模块职责 模块 职责 关键类 xtools-boot-api API基础定义:统一响应、异常体系、枚举、日志追踪模型、分页/树形模型 Result, BizError, LogTrack, PageReq, PageResp, TreeResp xtools-boot-core 核心工具集:Spring上下文、路径匹配、枚举工具、时间工具、树形工具、JAR工具 SpringContextUtils, PathPatternUtils, TreeUtils, TimeUtils xtools-boot-cache Redis缓存服务:数据缓存、分布式锁、Hash操作、缓存监控 RedisService, RedisUtils, RedisMonitor xtools-boot-db 数据库访问:MyBatis配置、MyBatis-Plus增强、Druid连接池、SQL监控、MySQL监控 BootDbMybatisConfiguration, BootDbMybatisPlusConfiguration, MySqlMonitor xtools-boot-elasticsearch 搜索引擎:ES查询构建、ES操作、ES监控 EsUtils, EsQueryUtils, ElasticsearchMonitor xtools-boot-ip IP地址工具:IP库初始化、IP地址查询和定位 IpUtils, InitIp xtools-boot-job 任务调度:XXL-JOB配置和初始化 XxlJobConfig, InitXxlJob xtools-boot-knife4j API文档:Knife4j集成和白名单配置 BootKnife4jConfiguration, Knife4jFilterWhitelist xtools-boot-log 日志总线:日志采集、格式化、异步持久化、日志追踪 LogBus, LogTrackHolder, LogBody, RunInfo xtools-boot-mask 数据脱敏:字段级脱敏注解、多种脱敏类型、自定义脱敏 @Mask, MaskSerializer, MaskType, DefaultMaskHandle xtools-boot-mq 消息队列:消息总线、RabbitMQ实现、消息编解码、错误处理 MqBus, RabbitMqHandle, BaseMessageHandle, MqMessageUtils xtools-boot-storage 存储抽象:统一存储接口、本地文件实现、S3实现 StorageService, StorageServiceFileImpl, StorageServiceS3Impl xtools-boot-task 任务总线:任务状态管理、任务信息持久化 TaskBus, TaskInfo, TaskStatus xtools-boot-thread 线程工具:虚拟线程执行、异步回调 VirtualThreadTaskUtils, VirtualThreadTaskCallback xtools-boot-web Web基础:全局异常处理、日志追踪Filter、Jackson定制、XSS过滤、过滤器链 GlobalControllerExceptionHandler, LogTrackFilter, CommonFilter 2.4 包结构设计 复制代码 xtools.boot.{module} ├── {Module}Configuration # 模块配置类(@Import ImportSelector) ├── selector │ └── {Module}ImportSelector # 自动导入选择器 ├── config # 模块配置属性 ├── constant # 常量定义 ├── enums # 枚举定义 ├── interfaces # 接口定义 │ ├── BusInterface # 总线接口(LogBusInterface, TaskBusInterface, MqEnums) │ └── BaseType # 基础类型接口(BaseEnum, BaseTaskType) ├── model │ └── dto # 数据传输对象 ├── utils # 工具类 ├── handle # 处理器 ├── filter # 过滤器 ├── init # 初始化(ApplicationRunner) ├── monitor # 监控组件 ├── holder # 持有器(ScopedValue) ├── service # 服务接口和实现 └── annotation # 自定义注解 2.5 模块自动装配设计 所有模块采用统一的自动装配模式: #mq6cxh344sd269atlkm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cxh344sd269atlkm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cxh344sd269atlkm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cxh344sd269atlkm .error-icon{fill:#a44141;}#mq6cxh344sd269atlkm .error-text{fill:#ddd;stroke:#ddd;}#mq6cxh344sd269atlkm .edge-thickness-normal{stroke-width:1px;}#mq6cxh344sd269atlkm .edge-thickness-thick{stroke-width:3.5px;}#mq6cxh344sd269atlkm .edge-pattern-solid{stroke-dasharray:0;}#mq6cxh344sd269atlkm .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cxh344sd269atlkm .edge-pattern-dashed{stroke-dasharray:3;}#mq6cxh344sd269atlkm .edge-pattern-dotted{stroke-dasharray:2;}#mq6cxh344sd269atlkm .marker{fill:lightgrey;stroke:lightgrey;}#mq6cxh344sd269atlkm .marker.cross{stroke:lightgrey;}#mq6cxh344sd269atlkm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cxh344sd269atlkm p{margin:0;}#mq6cxh344sd269atlkm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cxh344sd269atlkm .cluster-label text{fill:#F9FFFE;}#mq6cxh344sd269atlkm .cluster-label span{color:#F9FFFE;}#mq6cxh344sd269atlkm .cluster-label span p{background-color:transparent;}#mq6cxh344sd269atlkm .label text,#mq6cxh344sd269atlkm span{fill:#ccc;color:#ccc;}#mq6cxh344sd269atlkm .node rect,#mq6cxh344sd269atlkm .node circle,#mq6cxh344sd269atlkm .node ellipse,#mq6cxh344sd269atlkm .node polygon,#mq6cxh344sd269atlkm .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cxh344sd269atlkm .rough-node .label text,#mq6cxh344sd269atlkm .node .label text,#mq6cxh344sd269atlkm .image-shape .label,#mq6cxh344sd269atlkm .icon-shape .label{text-anchor:middle;}#mq6cxh344sd269atlkm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cxh344sd269atlkm .rough-node .label,#mq6cxh344sd269atlkm .node .label,#mq6cxh344sd269atlkm .image-shape .label,#mq6cxh344sd269atlkm .icon-shape .label{text-align:center;}#mq6cxh344sd269atlkm .node.clickable{cursor:pointer;}#mq6cxh344sd269atlkm .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cxh344sd269atlkm .arrowheadPath{fill:lightgrey;}#mq6cxh344sd269atlkm .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cxh344sd269atlkm .flowchart-link{stroke:lightgrey;fill:none;}#mq6cxh344sd269atlkm .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cxh344sd269atlkm .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cxh344sd269atlkm .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cxh344sd269atlkm .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cxh344sd269atlkm .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cxh344sd269atlkm .cluster text{fill:#F9FFFE;}#mq6cxh344sd269atlkm .cluster span{color:#F9FFFE;}#mq6cxh344sd269atlkm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cxh344sd269atlkm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cxh344sd269atlkm rect.text{fill:none;stroke-width:0;}#mq6cxh344sd269atlkm .icon-shape,#mq6cxh344sd269atlkm .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cxh344sd269atlkm .icon-shape p,#mq6cxh344sd269atlkm .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cxh344sd269atlkm .icon-shape rect,#mq6cxh344sd269atlkm .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cxh344sd269atlkm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cxh344sd269atlkm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cxh344sd269atlkm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}业务应用引入模块依赖模块Configuration类 @ConfigurationImportSelector通过 @Import导入扫描模块包路径registerBeanDefinitions注册模块内所有ComponentConfiguration / Utils / Monitor等设计原则: 每个模块通过 @Configuration + @Import(ImportSelector) 实现按需加载 ImportSelector 指定模块的根包路径,自动注册所有 @Component、@Configuration 等注解的类 业务应用只需引入对应模块的 Maven 依赖,无需手动配置 三、项目功能设计 3.1 统一响应与异常设计 统一响应模型 java 复制代码 public final class Result<T> { private boolean success; // 是否成功 private int code; // 响应代码 private Object msg; // 提示信息 private T data; // 响应数据 } 异常体系 #mq6cndsgjok64yhnldg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgjok64yhnldg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgjok64yhnldg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgjok64yhnldg .error-icon{fill:#a44141;}#mq6cndsgjok64yhnldg .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgjok64yhnldg .edge-thickness-normal{stroke-width:1px;}#mq6cndsgjok64yhnldg .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgjok64yhnldg .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgjok64yhnldg .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgjok64yhnldg .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgjok64yhnldg .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgjok64yhnldg .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgjok64yhnldg .marker.cross{stroke:lightgrey;}#mq6cndsgjok64yhnldg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgjok64yhnldg p{margin:0;}#mq6cndsgjok64yhnldg .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgjok64yhnldg .cluster-label text{fill:#F9FFFE;}#mq6cndsgjok64yhnldg .cluster-label span{color:#F9FFFE;}#mq6cndsgjok64yhnldg .cluster-label span p{background-color:transparent;}#mq6cndsgjok64yhnldg .label text,#mq6cndsgjok64yhnldg span{fill:#ccc;color:#ccc;}#mq6cndsgjok64yhnldg .node rect,#mq6cndsgjok64yhnldg .node circle,#mq6cndsgjok64yhnldg .node ellipse,#mq6cndsgjok64yhnldg .node polygon,#mq6cndsgjok64yhnldg .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgjok64yhnldg .rough-node .label text,#mq6cndsgjok64yhnldg .node .label text,#mq6cndsgjok64yhnldg .image-shape .label,#mq6cndsgjok64yhnldg .icon-shape .label{text-anchor:middle;}#mq6cndsgjok64yhnldg .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgjok64yhnldg .rough-node .label,#mq6cndsgjok64yhnldg .node .label,#mq6cndsgjok64yhnldg .image-shape .label,#mq6cndsgjok64yhnldg .icon-shape .label{text-align:center;}#mq6cndsgjok64yhnldg .node.clickable{cursor:pointer;}#mq6cndsgjok64yhnldg .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgjok64yhnldg .arrowheadPath{fill:lightgrey;}#mq6cndsgjok64yhnldg .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgjok64yhnldg .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgjok64yhnldg .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgjok64yhnldg .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgjok64yhnldg .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgjok64yhnldg .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgjok64yhnldg .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgjok64yhnldg .cluster text{fill:#F9FFFE;}#mq6cndsgjok64yhnldg .cluster span{color:#F9FFFE;}#mq6cndsgjok64yhnldg div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgjok64yhnldg .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgjok64yhnldg rect.text{fill:none;stroke-width:0;}#mq6cndsgjok64yhnldg .icon-shape,#mq6cndsgjok64yhnldg .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgjok64yhnldg .icon-shape p,#mq6cndsgjok64yhnldg .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgjok64yhnldg .icon-shape rect,#mq6cndsgjok64yhnldg .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgjok64yhnldg .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgjok64yhnldg .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgjok64yhnldg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}code >= 1000code >= 1000code >= 1000code=401CommonExceptionxtools-coreBizError业务异常BizWarning业务警告BizPublicKeyError公钥异常UnauthorizedError认证异常返回Result.success=truecode=业务码返回ResultType.UNAUTHORIZED全局异常处理流程 #mq6cndsgq4ptrynjta{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgq4ptrynjta .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgq4ptrynjta .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgq4ptrynjta .error-icon{fill:#a44141;}#mq6cndsgq4ptrynjta .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgq4ptrynjta .edge-thickness-normal{stroke-width:1px;}#mq6cndsgq4ptrynjta .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgq4ptrynjta .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgq4ptrynjta .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgq4ptrynjta .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgq4ptrynjta .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgq4ptrynjta .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgq4ptrynjta .marker.cross{stroke:lightgrey;}#mq6cndsgq4ptrynjta svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgq4ptrynjta p{margin:0;}#mq6cndsgq4ptrynjta .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgq4ptrynjta .cluster-label text{fill:#F9FFFE;}#mq6cndsgq4ptrynjta .cluster-label span{color:#F9FFFE;}#mq6cndsgq4ptrynjta .cluster-label span p{background-color:transparent;}#mq6cndsgq4ptrynjta .label text,#mq6cndsgq4ptrynjta span{fill:#ccc;color:#ccc;}#mq6cndsgq4ptrynjta .node rect,#mq6cndsgq4ptrynjta .node circle,#mq6cndsgq4ptrynjta .node ellipse,#mq6cndsgq4ptrynjta .node polygon,#mq6cndsgq4ptrynjta .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgq4ptrynjta .rough-node .label text,#mq6cndsgq4ptrynjta .node .label text,#mq6cndsgq4ptrynjta .image-shape .label,#mq6cndsgq4ptrynjta .icon-shape .label{text-anchor:middle;}#mq6cndsgq4ptrynjta .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgq4ptrynjta .rough-node .label,#mq6cndsgq4ptrynjta .node .label,#mq6cndsgq4ptrynjta .image-shape .label,#mq6cndsgq4ptrynjta .icon-shape .label{text-align:center;}#mq6cndsgq4ptrynjta .node.clickable{cursor:pointer;}#mq6cndsgq4ptrynjta .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgq4ptrynjta .arrowheadPath{fill:lightgrey;}#mq6cndsgq4ptrynjta .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgq4ptrynjta .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgq4ptrynjta .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgq4ptrynjta .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgq4ptrynjta .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgq4ptrynjta .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgq4ptrynjta .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgq4ptrynjta .cluster text{fill:#F9FFFE;}#mq6cndsgq4ptrynjta .cluster span{color:#F9FFFE;}#mq6cndsgq4ptrynjta div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgq4ptrynjta .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgq4ptrynjta rect.text{fill:none;stroke-width:0;}#mq6cndsgq4ptrynjta .icon-shape,#mq6cndsgq4ptrynjta .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgq4ptrynjta .icon-shape p,#mq6cndsgq4ptrynjta .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgq4ptrynjta .icon-shape rect,#mq6cndsgq4ptrynjta .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgq4ptrynjta .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgq4ptrynjta .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgq4ptrynjta :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}MethodArgumentTypeMismatchExceptionHandlerMethodValidationExceptionMethodArgumentNotValidExceptionHttpMessageNotReadableExceptionBizErrorBizWarningBizPublicKeyErrorUnauthorizedErrorHttpRequestMethodNotSupportedExceptionNoResourceFoundExceptionClientAbortExceptionExceptionController抛出异常异常类型参数类型不匹配参数校验异常参数校验异常请求参数格式错误业务异常业务警告公钥错误认证异常请求方法不支持资源未找到客户端断开默认异常处理返回 badRequest返回 business code返回 401 UNAUTHORIZED返回 405 METHOD_NOT_ALLOWED返回 404 NOT_FOUND静默处理返回 500 INTERNAL_SERVER_ERRORLogBus记录日志3.2 日志管理设计 日志总线架构 #mq6cndsgbjsbg0pk58v{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgbjsbg0pk58v .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgbjsbg0pk58v .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgbjsbg0pk58v .error-icon{fill:#a44141;}#mq6cndsgbjsbg0pk58v .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgbjsbg0pk58v .edge-thickness-normal{stroke-width:1px;}#mq6cndsgbjsbg0pk58v .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgbjsbg0pk58v .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgbjsbg0pk58v .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgbjsbg0pk58v .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgbjsbg0pk58v .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgbjsbg0pk58v .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgbjsbg0pk58v .marker.cross{stroke:lightgrey;}#mq6cndsgbjsbg0pk58v svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgbjsbg0pk58v p{margin:0;}#mq6cndsgbjsbg0pk58v .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgbjsbg0pk58v .cluster-label text{fill:#F9FFFE;}#mq6cndsgbjsbg0pk58v .cluster-label span{color:#F9FFFE;}#mq6cndsgbjsbg0pk58v .cluster-label span p{background-color:transparent;}#mq6cndsgbjsbg0pk58v .label text,#mq6cndsgbjsbg0pk58v span{fill:#ccc;color:#ccc;}#mq6cndsgbjsbg0pk58v .node rect,#mq6cndsgbjsbg0pk58v .node circle,#mq6cndsgbjsbg0pk58v .node ellipse,#mq6cndsgbjsbg0pk58v .node polygon,#mq6cndsgbjsbg0pk58v .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgbjsbg0pk58v .rough-node .label text,#mq6cndsgbjsbg0pk58v .node .label text,#mq6cndsgbjsbg0pk58v .image-shape .label,#mq6cndsgbjsbg0pk58v .icon-shape .label{text-anchor:middle;}#mq6cndsgbjsbg0pk58v .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgbjsbg0pk58v .rough-node .label,#mq6cndsgbjsbg0pk58v .node .label,#mq6cndsgbjsbg0pk58v .image-shape .label,#mq6cndsgbjsbg0pk58v .icon-shape .label{text-align:center;}#mq6cndsgbjsbg0pk58v .node.clickable{cursor:pointer;}#mq6cndsgbjsbg0pk58v .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgbjsbg0pk58v .arrowheadPath{fill:lightgrey;}#mq6cndsgbjsbg0pk58v .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgbjsbg0pk58v .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgbjsbg0pk58v .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgbjsbg0pk58v .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgbjsbg0pk58v .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgbjsbg0pk58v .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgbjsbg0pk58v .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgbjsbg0pk58v .cluster text{fill:#F9FFFE;}#mq6cndsgbjsbg0pk58v .cluster span{color:#F9FFFE;}#mq6cndsgbjsbg0pk58v div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgbjsbg0pk58v .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgbjsbg0pk58v rect.text{fill:none;stroke-width:0;}#mq6cndsgbjsbg0pk58v .icon-shape,#mq6cndsgbjsbg0pk58v .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgbjsbg0pk58v .icon-shape p,#mq6cndsgbjsbg0pk58v .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgbjsbg0pk58v .icon-shape rect,#mq6cndsgbjsbg0pk58v .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgbjsbg0pk58v .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgbjsbg0pk58v .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgbjsbg0pk58v :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}是否是否否是日志产生方LogBus.init设置日志级别设置日志类型设置标题附加数据data附加异常errorsave创建虚拟线程格式化堆栈信息是否打印?格式化日志输出到控制台跳过打印日志级别>=WARN?必须保存日志logTrack.save?跳过保存处理日志超长截断处理异常信息获取所有LogBusInterface逐个调用save方法日志追踪设计 #mq6cndsgq15p5c1hbg9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgq15p5c1hbg9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgq15p5c1hbg9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgq15p5c1hbg9 .error-icon{fill:#a44141;}#mq6cndsgq15p5c1hbg9 .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgq15p5c1hbg9 .edge-thickness-normal{stroke-width:1px;}#mq6cndsgq15p5c1hbg9 .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgq15p5c1hbg9 .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgq15p5c1hbg9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgq15p5c1hbg9 .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgq15p5c1hbg9 .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgq15p5c1hbg9 .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgq15p5c1hbg9 .marker.cross{stroke:lightgrey;}#mq6cndsgq15p5c1hbg9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgq15p5c1hbg9 p{margin:0;}#mq6cndsgq15p5c1hbg9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgq15p5c1hbg9 .cluster-label text{fill:#F9FFFE;}#mq6cndsgq15p5c1hbg9 .cluster-label span{color:#F9FFFE;}#mq6cndsgq15p5c1hbg9 .cluster-label span p{background-color:transparent;}#mq6cndsgq15p5c1hbg9 .label text,#mq6cndsgq15p5c1hbg9 span{fill:#ccc;color:#ccc;}#mq6cndsgq15p5c1hbg9 .node rect,#mq6cndsgq15p5c1hbg9 .node circle,#mq6cndsgq15p5c1hbg9 .node ellipse,#mq6cndsgq15p5c1hbg9 .node polygon,#mq6cndsgq15p5c1hbg9 .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgq15p5c1hbg9 .rough-node .label text,#mq6cndsgq15p5c1hbg9 .node .label text,#mq6cndsgq15p5c1hbg9 .image-shape .label,#mq6cndsgq15p5c1hbg9 .icon-shape .label{text-anchor:middle;}#mq6cndsgq15p5c1hbg9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgq15p5c1hbg9 .rough-node .label,#mq6cndsgq15p5c1hbg9 .node .label,#mq6cndsgq15p5c1hbg9 .image-shape .label,#mq6cndsgq15p5c1hbg9 .icon-shape .label{text-align:center;}#mq6cndsgq15p5c1hbg9 .node.clickable{cursor:pointer;}#mq6cndsgq15p5c1hbg9 .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgq15p5c1hbg9 .arrowheadPath{fill:lightgrey;}#mq6cndsgq15p5c1hbg9 .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgq15p5c1hbg9 .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgq15p5c1hbg9 .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgq15p5c1hbg9 .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgq15p5c1hbg9 .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgq15p5c1hbg9 .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgq15p5c1hbg9 .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgq15p5c1hbg9 .cluster text{fill:#F9FFFE;}#mq6cndsgq15p5c1hbg9 .cluster span{color:#F9FFFE;}#mq6cndsgq15p5c1hbg9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgq15p5c1hbg9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgq15p5c1hbg9 rect.text{fill:none;stroke-width:0;}#mq6cndsgq15p5c1hbg9 .icon-shape,#mq6cndsgq15p5c1hbg9 .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgq15p5c1hbg9 .icon-shape p,#mq6cndsgq15p5c1hbg9 .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgq15p5c1hbg9 .icon-shape rect,#mq6cndsgq15p5c1hbg9 .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgq15p5c1hbg9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgq15p5c1hbg9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgq15p5c1hbg9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}HTTP请求到达LogTrackFilterOrder:100创建LogTrack生成唯一ID生成traceId设置type=MAIN设置save=true绑定到ScopedValue子线程/虚拟线程从父线程获取LogTrack创建子LogTrack继承traceId设置type=THREAD绑定到新ScopedValueLogBus使用LogTrackHolder获取日志类型枚举 日志类型 说明 OTHER 其他 VIRTUAL_THREAD 虚拟线程 REDIS Redis操作 MYBATIS MyBatis操作 MQ 消息队列 ELASTICSEARCH Elasticsearch操作 SENTINEL Sentinel操作 STORAGE 存储操作 OPT_LOG 操作日志 HTTP HTTP操作 HTTP_REQUEST HTTP请求 HTTP_RESPONSE HTTP响应 CLOUD_REQUEST 云端请求 CLOUD_RESPONSE 云端响应 CONTROLLER Controller异常 TASK 任务操作 JOB 定时任务 RISK 风险操作 3.3 缓存设计 Redis服务架构 #mq6cndsgbhyih8h0jid{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgbhyih8h0jid .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgbhyih8h0jid .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgbhyih8h0jid .error-icon{fill:#a44141;}#mq6cndsgbhyih8h0jid .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgbhyih8h0jid .edge-thickness-normal{stroke-width:1px;}#mq6cndsgbhyih8h0jid .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgbhyih8h0jid .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgbhyih8h0jid .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgbhyih8h0jid .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgbhyih8h0jid .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgbhyih8h0jid .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgbhyih8h0jid .marker.cross{stroke:lightgrey;}#mq6cndsgbhyih8h0jid svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgbhyih8h0jid p{margin:0;}#mq6cndsgbhyih8h0jid .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgbhyih8h0jid .cluster-label text{fill:#F9FFFE;}#mq6cndsgbhyih8h0jid .cluster-label span{color:#F9FFFE;}#mq6cndsgbhyih8h0jid .cluster-label span p{background-color:transparent;}#mq6cndsgbhyih8h0jid .label text,#mq6cndsgbhyih8h0jid span{fill:#ccc;color:#ccc;}#mq6cndsgbhyih8h0jid .node rect,#mq6cndsgbhyih8h0jid .node circle,#mq6cndsgbhyih8h0jid .node ellipse,#mq6cndsgbhyih8h0jid .node polygon,#mq6cndsgbhyih8h0jid .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgbhyih8h0jid .rough-node .label text,#mq6cndsgbhyih8h0jid .node .label text,#mq6cndsgbhyih8h0jid .image-shape .label,#mq6cndsgbhyih8h0jid .icon-shape .label{text-anchor:middle;}#mq6cndsgbhyih8h0jid .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgbhyih8h0jid .rough-node .label,#mq6cndsgbhyih8h0jid .node .label,#mq6cndsgbhyih8h0jid .image-shape .label,#mq6cndsgbhyih8h0jid .icon-shape .label{text-align:center;}#mq6cndsgbhyih8h0jid .node.clickable{cursor:pointer;}#mq6cndsgbhyih8h0jid .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgbhyih8h0jid .arrowheadPath{fill:lightgrey;}#mq6cndsgbhyih8h0jid .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgbhyih8h0jid .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgbhyih8h0jid .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgbhyih8h0jid .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgbhyih8h0jid .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgbhyih8h0jid .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgbhyih8h0jid .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgbhyih8h0jid .cluster text{fill:#F9FFFE;}#mq6cndsgbhyih8h0jid .cluster span{color:#F9FFFE;}#mq6cndsgbhyih8h0jid div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgbhyih8h0jid .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgbhyih8h0jid rect.text{fill:none;stroke-width:0;}#mq6cndsgbhyih8h0jid .icon-shape,#mq6cndsgbhyih8h0jid .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgbhyih8h0jid .icon-shape p,#mq6cndsgbhyih8h0jid .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgbhyih8h0jid .icon-shape rect,#mq6cndsgbhyih8h0jid .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgbhyih8h0jid .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgbhyih8h0jid .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgbhyih8h0jid :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}底层序列化RedisServiceString操作set / get / del / incrKey操作expire / persist / renamegetByPattern / getKey分布式锁tryLock / releaseLockLua脚本保证原子性Hash操作hashPut / hashGethashEntries / hashDeletehashExists原子操作setNx / hashPut带过期FastJSON2序列化String直接存储Object序列化为JSONStringRedisTemplate字符串操作RedisTemplate分布式锁DefaultRedisScriptLua脚本3.4 消息队列设计 消息总线架构 #mq6cndsgvj4mw6tvfyd{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgvj4mw6tvfyd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgvj4mw6tvfyd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgvj4mw6tvfyd .error-icon{fill:#a44141;}#mq6cndsgvj4mw6tvfyd .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgvj4mw6tvfyd .edge-thickness-normal{stroke-width:1px;}#mq6cndsgvj4mw6tvfyd .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgvj4mw6tvfyd .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgvj4mw6tvfyd .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgvj4mw6tvfyd .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgvj4mw6tvfyd .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgvj4mw6tvfyd .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgvj4mw6tvfyd .marker.cross{stroke:lightgrey;}#mq6cndsgvj4mw6tvfyd svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgvj4mw6tvfyd p{margin:0;}#mq6cndsgvj4mw6tvfyd .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgvj4mw6tvfyd .cluster-label text{fill:#F9FFFE;}#mq6cndsgvj4mw6tvfyd .cluster-label span{color:#F9FFFE;}#mq6cndsgvj4mw6tvfyd .cluster-label span p{background-color:transparent;}#mq6cndsgvj4mw6tvfyd .label text,#mq6cndsgvj4mw6tvfyd span{fill:#ccc;color:#ccc;}#mq6cndsgvj4mw6tvfyd .node rect,#mq6cndsgvj4mw6tvfyd .node circle,#mq6cndsgvj4mw6tvfyd .node ellipse,#mq6cndsgvj4mw6tvfyd .node polygon,#mq6cndsgvj4mw6tvfyd .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgvj4mw6tvfyd .rough-node .label text,#mq6cndsgvj4mw6tvfyd .node .label text,#mq6cndsgvj4mw6tvfyd .image-shape .label,#mq6cndsgvj4mw6tvfyd .icon-shape .label{text-anchor:middle;}#mq6cndsgvj4mw6tvfyd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgvj4mw6tvfyd .rough-node .label,#mq6cndsgvj4mw6tvfyd .node .label,#mq6cndsgvj4mw6tvfyd .image-shape .label,#mq6cndsgvj4mw6tvfyd .icon-shape .label{text-align:center;}#mq6cndsgvj4mw6tvfyd .node.clickable{cursor:pointer;}#mq6cndsgvj4mw6tvfyd .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgvj4mw6tvfyd .arrowheadPath{fill:lightgrey;}#mq6cndsgvj4mw6tvfyd .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgvj4mw6tvfyd .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgvj4mw6tvfyd .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgvj4mw6tvfyd .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgvj4mw6tvfyd .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgvj4mw6tvfyd .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgvj4mw6tvfyd .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgvj4mw6tvfyd .cluster text{fill:#F9FFFE;}#mq6cndsgvj4mw6tvfyd .cluster span{color:#F9FFFE;}#mq6cndsgvj4mw6tvfyd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgvj4mw6tvfyd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgvj4mw6tvfyd rect.text{fill:none;stroke-width:0;}#mq6cndsgvj4mw6tvfyd .icon-shape,#mq6cndsgvj4mw6tvfyd .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgvj4mw6tvfyd .icon-shape p,#mq6cndsgvj4mw6tvfyd .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgvj4mw6tvfyd .icon-shape rect,#mq6cndsgvj4mw6tvfyd .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgvj4mw6tvfyd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgvj4mw6tvfyd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgvj4mw6tvfyd :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}是否成功失败业务代码调用MqBus.push获取BaseMqHandle实现是否存在实现?调用push方法抛出异常RabbitMqHandle.push消息序列化MqMessageUtils.toRabbitTemplate发送RabbitMQ Broker消费者接收消息反序列化MqMessageUtils.fromBaseMessageHandlebaseHandleMessage业务处理消息确认ACKBaseErrorHandle错误处理消息初始化流程 #mq6cndsgsan56liqjw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgsan56liqjw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgsan56liqjw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgsan56liqjw .error-icon{fill:#a44141;}#mq6cndsgsan56liqjw .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgsan56liqjw .edge-thickness-normal{stroke-width:1px;}#mq6cndsgsan56liqjw .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgsan56liqjw .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgsan56liqjw .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgsan56liqjw .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgsan56liqjw .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgsan56liqjw .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgsan56liqjw .marker.cross{stroke:lightgrey;}#mq6cndsgsan56liqjw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgsan56liqjw p{margin:0;}#mq6cndsgsan56liqjw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgsan56liqjw .cluster-label text{fill:#F9FFFE;}#mq6cndsgsan56liqjw .cluster-label span{color:#F9FFFE;}#mq6cndsgsan56liqjw .cluster-label span p{background-color:transparent;}#mq6cndsgsan56liqjw .label text,#mq6cndsgsan56liqjw span{fill:#ccc;color:#ccc;}#mq6cndsgsan56liqjw .node rect,#mq6cndsgsan56liqjw .node circle,#mq6cndsgsan56liqjw .node ellipse,#mq6cndsgsan56liqjw .node polygon,#mq6cndsgsan56liqjw .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgsan56liqjw .rough-node .label text,#mq6cndsgsan56liqjw .node .label text,#mq6cndsgsan56liqjw .image-shape .label,#mq6cndsgsan56liqjw .icon-shape .label{text-anchor:middle;}#mq6cndsgsan56liqjw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgsan56liqjw .rough-node .label,#mq6cndsgsan56liqjw .node .label,#mq6cndsgsan56liqjw .image-shape .label,#mq6cndsgsan56liqjw .icon-shape .label{text-align:center;}#mq6cndsgsan56liqjw .node.clickable{cursor:pointer;}#mq6cndsgsan56liqjw .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgsan56liqjw .arrowheadPath{fill:lightgrey;}#mq6cndsgsan56liqjw .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgsan56liqjw .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgsan56liqjw .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgsan56liqjw .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgsan56liqjw .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgsan56liqjw .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgsan56liqjw .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgsan56liqjw .cluster text{fill:#F9FFFE;}#mq6cndsgsan56liqjw .cluster span{color:#F9FFFE;}#mq6cndsgsan56liqjw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgsan56liqjw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgsan56liqjw rect.text{fill:none;stroke-width:0;}#mq6cndsgsan56liqjw .icon-shape,#mq6cndsgsan56liqjw .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgsan56liqjw .icon-shape p,#mq6cndsgsan56liqjw .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgsan56liqjw .icon-shape rect,#mq6cndsgsan56liqjw .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgsan56liqjw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgsan56liqjw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgsan56liqjw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}应用启动InitMqApplicationRunner Order:50获取所有BaseMqHandle实现逐个调用initQueue初始化队列添加监听器addListen消息队列就绪3.5 存储设计 存储抽象架构 #mq6cndsgpnjtpssl6dl{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgpnjtpssl6dl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgpnjtpssl6dl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgpnjtpssl6dl .error-icon{fill:#a44141;}#mq6cndsgpnjtpssl6dl .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgpnjtpssl6dl .edge-thickness-normal{stroke-width:1px;}#mq6cndsgpnjtpssl6dl .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgpnjtpssl6dl .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgpnjtpssl6dl .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgpnjtpssl6dl .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgpnjtpssl6dl .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgpnjtpssl6dl .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgpnjtpssl6dl .marker.cross{stroke:lightgrey;}#mq6cndsgpnjtpssl6dl svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgpnjtpssl6dl p{margin:0;}#mq6cndsgpnjtpssl6dl .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgpnjtpssl6dl .cluster-label text{fill:#F9FFFE;}#mq6cndsgpnjtpssl6dl .cluster-label span{color:#F9FFFE;}#mq6cndsgpnjtpssl6dl .cluster-label span p{background-color:transparent;}#mq6cndsgpnjtpssl6dl .label text,#mq6cndsgpnjtpssl6dl span{fill:#ccc;color:#ccc;}#mq6cndsgpnjtpssl6dl .node rect,#mq6cndsgpnjtpssl6dl .node circle,#mq6cndsgpnjtpssl6dl .node ellipse,#mq6cndsgpnjtpssl6dl .node polygon,#mq6cndsgpnjtpssl6dl .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgpnjtpssl6dl .rough-node .label text,#mq6cndsgpnjtpssl6dl .node .label text,#mq6cndsgpnjtpssl6dl .image-shape .label,#mq6cndsgpnjtpssl6dl .icon-shape .label{text-anchor:middle;}#mq6cndsgpnjtpssl6dl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgpnjtpssl6dl .rough-node .label,#mq6cndsgpnjtpssl6dl .node .label,#mq6cndsgpnjtpssl6dl .image-shape .label,#mq6cndsgpnjtpssl6dl .icon-shape .label{text-align:center;}#mq6cndsgpnjtpssl6dl .node.clickable{cursor:pointer;}#mq6cndsgpnjtpssl6dl .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgpnjtpssl6dl .arrowheadPath{fill:lightgrey;}#mq6cndsgpnjtpssl6dl .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgpnjtpssl6dl .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgpnjtpssl6dl .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgpnjtpssl6dl .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgpnjtpssl6dl .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgpnjtpssl6dl .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgpnjtpssl6dl .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgpnjtpssl6dl .cluster text{fill:#F9FFFE;}#mq6cndsgpnjtpssl6dl .cluster span{color:#F9FFFE;}#mq6cndsgpnjtpssl6dl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgpnjtpssl6dl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgpnjtpssl6dl rect.text{fill:none;stroke-width:0;}#mq6cndsgpnjtpssl6dl .icon-shape,#mq6cndsgpnjtpssl6dl .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgpnjtpssl6dl .icon-shape p,#mq6cndsgpnjtpssl6dl .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgpnjtpssl6dl .icon-shape rect,#mq6cndsgpnjtpssl6dl .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgpnjtpssl6dl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgpnjtpssl6dl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgpnjtpssl6dl :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}配置层实现层存储接口实现实现type=filetype=s3StorageService接口StorageServiceFileImpl本地文件存储StorageServiceS3ImplS3对象存储StorageConfig存储类型配置FileStorageConfig文件存储配置S3StorageConfigS3配置+S3ClientStorageService接口方法: 方法 说明 exists(String key) 判断文件是否存在 save(String key, InputStream data) 保存文件 get(String key) 获取文件输入流 del(String key) 删除文件 3.6 数据脱敏设计 脱敏注解 #mq6cw7t8d3fwiruff5m{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cw7t8d3fwiruff5m .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cw7t8d3fwiruff5m .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cw7t8d3fwiruff5m .error-icon{fill:#a44141;}#mq6cw7t8d3fwiruff5m .error-text{fill:#ddd;stroke:#ddd;}#mq6cw7t8d3fwiruff5m .edge-thickness-normal{stroke-width:1px;}#mq6cw7t8d3fwiruff5m .edge-thickness-thick{stroke-width:3.5px;}#mq6cw7t8d3fwiruff5m .edge-pattern-solid{stroke-dasharray:0;}#mq6cw7t8d3fwiruff5m .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cw7t8d3fwiruff5m .edge-pattern-dashed{stroke-dasharray:3;}#mq6cw7t8d3fwiruff5m .edge-pattern-dotted{stroke-dasharray:2;}#mq6cw7t8d3fwiruff5m .marker{fill:lightgrey;stroke:lightgrey;}#mq6cw7t8d3fwiruff5m .marker.cross{stroke:lightgrey;}#mq6cw7t8d3fwiruff5m svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cw7t8d3fwiruff5m p{margin:0;}#mq6cw7t8d3fwiruff5m .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cw7t8d3fwiruff5m .cluster-label text{fill:#F9FFFE;}#mq6cw7t8d3fwiruff5m .cluster-label span{color:#F9FFFE;}#mq6cw7t8d3fwiruff5m .cluster-label span p{background-color:transparent;}#mq6cw7t8d3fwiruff5m .label text,#mq6cw7t8d3fwiruff5m span{fill:#ccc;color:#ccc;}#mq6cw7t8d3fwiruff5m .node rect,#mq6cw7t8d3fwiruff5m .node circle,#mq6cw7t8d3fwiruff5m .node ellipse,#mq6cw7t8d3fwiruff5m .node polygon,#mq6cw7t8d3fwiruff5m .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cw7t8d3fwiruff5m .rough-node .label text,#mq6cw7t8d3fwiruff5m .node .label text,#mq6cw7t8d3fwiruff5m .image-shape .label,#mq6cw7t8d3fwiruff5m .icon-shape .label{text-anchor:middle;}#mq6cw7t8d3fwiruff5m .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cw7t8d3fwiruff5m .rough-node .label,#mq6cw7t8d3fwiruff5m .node .label,#mq6cw7t8d3fwiruff5m .image-shape .label,#mq6cw7t8d3fwiruff5m .icon-shape .label{text-align:center;}#mq6cw7t8d3fwiruff5m .node.clickable{cursor:pointer;}#mq6cw7t8d3fwiruff5m .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cw7t8d3fwiruff5m .arrowheadPath{fill:lightgrey;}#mq6cw7t8d3fwiruff5m .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cw7t8d3fwiruff5m .flowchart-link{stroke:lightgrey;fill:none;}#mq6cw7t8d3fwiruff5m .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cw7t8d3fwiruff5m .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cw7t8d3fwiruff5m .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cw7t8d3fwiruff5m .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cw7t8d3fwiruff5m .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cw7t8d3fwiruff5m .cluster text{fill:#F9FFFE;}#mq6cw7t8d3fwiruff5m .cluster span{color:#F9FFFE;}#mq6cw7t8d3fwiruff5m div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cw7t8d3fwiruff5m .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cw7t8d3fwiruff5m rect.text{fill:none;stroke-width:0;}#mq6cw7t8d3fwiruff5m .icon-shape,#mq6cw7t8d3fwiruff5m .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cw7t8d3fwiruff5m .icon-shape p,#mq6cw7t8d3fwiruff5m .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cw7t8d3fwiruff5m .icon-shape rect,#mq6cw7t8d3fwiruff5m .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cw7t8d3fwiruff5m .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cw7t8d3fwiruff5m .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cw7t8d3fwiruff5m :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}CHINESE_NAMEID_CARDMOBILE_PHONEEMAILBANK_CARDPASSWORDADDRESSCUSTOM是否是否实体类字段标注 @MaskMaskType类型姓名脱敏张三 -> 张*身份证脱敏110101199001011234 -> 110101****1234手机号脱敏13812345678 -> 138****5678邮箱脱敏test @example.com -> t***@example.com银行卡脱敏密码脱敏全部替换为***地址脱敏自定义脱敏实现MaskCustom接口Jackson序列化MaskSerializerMaskIgnoreUtils是否忽略脱敏?返回原始值执行脱敏处理always=true?必须脱敏可通过Holder忽略3.7 过滤器链设计 #mq6cndsgf39ojtqwujh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgf39ojtqwujh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgf39ojtqwujh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgf39ojtqwujh .error-icon{fill:#a44141;}#mq6cndsgf39ojtqwujh .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgf39ojtqwujh .edge-thickness-normal{stroke-width:1px;}#mq6cndsgf39ojtqwujh .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgf39ojtqwujh .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgf39ojtqwujh .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgf39ojtqwujh .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgf39ojtqwujh .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgf39ojtqwujh .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgf39ojtqwujh .marker.cross{stroke:lightgrey;}#mq6cndsgf39ojtqwujh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgf39ojtqwujh p{margin:0;}#mq6cndsgf39ojtqwujh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgf39ojtqwujh .cluster-label text{fill:#F9FFFE;}#mq6cndsgf39ojtqwujh .cluster-label span{color:#F9FFFE;}#mq6cndsgf39ojtqwujh .cluster-label span p{background-color:transparent;}#mq6cndsgf39ojtqwujh .label text,#mq6cndsgf39ojtqwujh span{fill:#ccc;color:#ccc;}#mq6cndsgf39ojtqwujh .node rect,#mq6cndsgf39ojtqwujh .node circle,#mq6cndsgf39ojtqwujh .node ellipse,#mq6cndsgf39ojtqwujh .node polygon,#mq6cndsgf39ojtqwujh .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgf39ojtqwujh .rough-node .label text,#mq6cndsgf39ojtqwujh .node .label text,#mq6cndsgf39ojtqwujh .image-shape .label,#mq6cndsgf39ojtqwujh .icon-shape .label{text-anchor:middle;}#mq6cndsgf39ojtqwujh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgf39ojtqwujh .rough-node .label,#mq6cndsgf39ojtqwujh .node .label,#mq6cndsgf39ojtqwujh .image-shape .label,#mq6cndsgf39ojtqwujh .icon-shape .label{text-align:center;}#mq6cndsgf39ojtqwujh .node.clickable{cursor:pointer;}#mq6cndsgf39ojtqwujh .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgf39ojtqwujh .arrowheadPath{fill:lightgrey;}#mq6cndsgf39ojtqwujh .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgf39ojtqwujh .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgf39ojtqwujh .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgf39ojtqwujh .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgf39ojtqwujh .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgf39ojtqwujh .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgf39ojtqwujh .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgf39ojtqwujh .cluster text{fill:#F9FFFE;}#mq6cndsgf39ojtqwujh .cluster span{color:#F9FFFE;}#mq6cndsgf39ojtqwujh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgf39ojtqwujh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgf39ojtqwujh rect.text{fill:none;stroke-width:0;}#mq6cndsgf39ojtqwujh .icon-shape,#mq6cndsgf39ojtqwujh .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgf39ojtqwujh .icon-shape p,#mq6cndsgf39ojtqwujh .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgf39ojtqwujh .icon-shape rect,#mq6cndsgf39ojtqwujh .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgf39ojtqwujh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgf39ojtqwujh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgf39ojtqwujh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}是否HTTP请求Order:0SkipFilter路径在白名单中?跳过后续Filter标记跳过继续执行Order:100LogTrackFilter创建LogTrack绑定到ScopedValueOrder:101CommonFilter绑定CommonHolder到ScopedValueController处理请求3.8 任务总线设计 #mq6cndsg0t9xlk0k74ve{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsg0t9xlk0k74ve .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsg0t9xlk0k74ve .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsg0t9xlk0k74ve .error-icon{fill:#a44141;}#mq6cndsg0t9xlk0k74ve .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsg0t9xlk0k74ve .edge-thickness-normal{stroke-width:1px;}#mq6cndsg0t9xlk0k74ve .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsg0t9xlk0k74ve .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsg0t9xlk0k74ve .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsg0t9xlk0k74ve .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsg0t9xlk0k74ve .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsg0t9xlk0k74ve .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsg0t9xlk0k74ve .marker.cross{stroke:lightgrey;}#mq6cndsg0t9xlk0k74ve svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsg0t9xlk0k74ve p{margin:0;}#mq6cndsg0t9xlk0k74ve .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsg0t9xlk0k74ve .cluster-label text{fill:#F9FFFE;}#mq6cndsg0t9xlk0k74ve .cluster-label span{color:#F9FFFE;}#mq6cndsg0t9xlk0k74ve .cluster-label span p{background-color:transparent;}#mq6cndsg0t9xlk0k74ve .label text,#mq6cndsg0t9xlk0k74ve span{fill:#ccc;color:#ccc;}#mq6cndsg0t9xlk0k74ve .node rect,#mq6cndsg0t9xlk0k74ve .node circle,#mq6cndsg0t9xlk0k74ve .node ellipse,#mq6cndsg0t9xlk0k74ve .node polygon,#mq6cndsg0t9xlk0k74ve .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsg0t9xlk0k74ve .rough-node .label text,#mq6cndsg0t9xlk0k74ve .node .label text,#mq6cndsg0t9xlk0k74ve .image-shape .label,#mq6cndsg0t9xlk0k74ve .icon-shape .label{text-anchor:middle;}#mq6cndsg0t9xlk0k74ve .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsg0t9xlk0k74ve .rough-node .label,#mq6cndsg0t9xlk0k74ve .node .label,#mq6cndsg0t9xlk0k74ve .image-shape .label,#mq6cndsg0t9xlk0k74ve .icon-shape .label{text-align:center;}#mq6cndsg0t9xlk0k74ve .node.clickable{cursor:pointer;}#mq6cndsg0t9xlk0k74ve .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsg0t9xlk0k74ve .arrowheadPath{fill:lightgrey;}#mq6cndsg0t9xlk0k74ve .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsg0t9xlk0k74ve .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsg0t9xlk0k74ve .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsg0t9xlk0k74ve .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsg0t9xlk0k74ve .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsg0t9xlk0k74ve .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsg0t9xlk0k74ve .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsg0t9xlk0k74ve .cluster text{fill:#F9FFFE;}#mq6cndsg0t9xlk0k74ve .cluster span{color:#F9FFFE;}#mq6cndsg0t9xlk0k74ve div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsg0t9xlk0k74ve .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsg0t9xlk0k74ve rect.text{fill:none;stroke-width:0;}#mq6cndsg0t9xlk0k74ve .icon-shape,#mq6cndsg0t9xlk0k74ve .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsg0t9xlk0k74ve .icon-shape p,#mq6cndsg0t9xlk0k74ve .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsg0t9xlk0k74ve .icon-shape rect,#mq6cndsg0t9xlk0k74ve .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsg0t9xlk0k74ve .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsg0t9xlk0k74ve .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsg0t9xlk0k74ve :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}任务开始TaskBus.initcode / type / statusTaskBus.info设置描述信息TaskBus.time设置任务时间TaskBus.save获取所有TaskBusInterface逐个调用save方法任务信息持久化任务状态枚举: 状态 值 说明 ING 0 进行中 SUCCESS 1 成功 ERROR 2 失败 3.9 虚拟线程设计 #mq6cndsgyeaw70zb53{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgyeaw70zb53 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgyeaw70zb53 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgyeaw70zb53 .error-icon{fill:#a44141;}#mq6cndsgyeaw70zb53 .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgyeaw70zb53 .edge-thickness-normal{stroke-width:1px;}#mq6cndsgyeaw70zb53 .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgyeaw70zb53 .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgyeaw70zb53 .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgyeaw70zb53 .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgyeaw70zb53 .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgyeaw70zb53 .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgyeaw70zb53 .marker.cross{stroke:lightgrey;}#mq6cndsgyeaw70zb53 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgyeaw70zb53 p{margin:0;}#mq6cndsgyeaw70zb53 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgyeaw70zb53 .cluster-label text{fill:#F9FFFE;}#mq6cndsgyeaw70zb53 .cluster-label span{color:#F9FFFE;}#mq6cndsgyeaw70zb53 .cluster-label span p{background-color:transparent;}#mq6cndsgyeaw70zb53 .label text,#mq6cndsgyeaw70zb53 span{fill:#ccc;color:#ccc;}#mq6cndsgyeaw70zb53 .node rect,#mq6cndsgyeaw70zb53 .node circle,#mq6cndsgyeaw70zb53 .node ellipse,#mq6cndsgyeaw70zb53 .node polygon,#mq6cndsgyeaw70zb53 .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgyeaw70zb53 .rough-node .label text,#mq6cndsgyeaw70zb53 .node .label text,#mq6cndsgyeaw70zb53 .image-shape .label,#mq6cndsgyeaw70zb53 .icon-shape .label{text-anchor:middle;}#mq6cndsgyeaw70zb53 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgyeaw70zb53 .rough-node .label,#mq6cndsgyeaw70zb53 .node .label,#mq6cndsgyeaw70zb53 .image-shape .label,#mq6cndsgyeaw70zb53 .icon-shape .label{text-align:center;}#mq6cndsgyeaw70zb53 .node.clickable{cursor:pointer;}#mq6cndsgyeaw70zb53 .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgyeaw70zb53 .arrowheadPath{fill:lightgrey;}#mq6cndsgyeaw70zb53 .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgyeaw70zb53 .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgyeaw70zb53 .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgyeaw70zb53 .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgyeaw70zb53 .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgyeaw70zb53 .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgyeaw70zb53 .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgyeaw70zb53 .cluster text{fill:#F9FFFE;}#mq6cndsgyeaw70zb53 .cluster span{color:#F9FFFE;}#mq6cndsgyeaw70zb53 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgyeaw70zb53 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgyeaw70zb53 rect.text{fill:none;stroke-width:0;}#mq6cndsgyeaw70zb53 .icon-shape,#mq6cndsgyeaw70zb53 .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgyeaw70zb53 .icon-shape p,#mq6cndsgyeaw70zb53 .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgyeaw70zb53 .icon-shape rect,#mq6cndsgyeaw70zb53 .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgyeaw70zb53 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgyeaw70zb53 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgyeaw70zb53 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}VirtualThreadTaskUtilssimple方法简单虚拟线程执行execute方法带回调的虚拟线程执行创建虚拟线程执行Runnable任务返回CompletableFuture创建虚拟线程执行任务VirtualThreadTaskCallbackonSuccess / onError四、编码规范设计 4.1 命名规范 类命名 类型 命名规范 示例 配置类 Boot{Module}Configuration BootCacheRedisConfiguration 导入选择器 Boot{Module}ImportSelector BootCacheRedisImportSelector 配置属性 {功能}Config LogBusConfig, StorageConfig 工具类 {功能}Utils RedisUtils, TreeUtils, TimeUtils 监控类 {组件}Monitor RedisMonitor, MySqlMonitor 枚举类 {功能}Enums / {功能}Enum MySqlMonitorEnums, MaskType 异常类 Biz{类型}Error BizError, BizWarning, BizPublicKeyError 接口 {功能}Interface / Base{功能} LogBusInterface, BaseTaskType DTO {功能}Dto / {功能} Result, LogBody, TaskInfo, RunInfo 总线 {功能}Bus LogBus, TaskBus, MqBus 初始化 Init{功能} InitIp, InitMq, InitXxlJob 处理器 {功能}Handle / {功能}Handler RabbitMqHandle, DefaultMaskHandle 持有器 {功能}Holder LogTrackHolder, CommonHolder 注解 {功能} @Mask, @IgnoreXss 方法命名 操作 前缀 示例 初始化 init LogBus.init(), TaskBus.init() 保存 save logBus.save(), taskBus.save() 获取 get RedisService.get(), hashGet() 删除 del RedisService.del(), hashDelete() 判断 is/has/exists hashExists() 格式化 fmt fmtLog(), fmtStackTrace() 执行 do doSave() 4.2 注释规范 类注释格式 java 复制代码 /** * <p>Title : 类名称</p> * <p>Description : 类描述</p> * <p>DevelopTools : Idea_x64_v2026.1</p> * <p>DevelopSystem : macOS Sequoia 15.7.5</p> * <p>Company : org.xujun</p> * * @author : XuJun * @version : 5.0.0 * @date : 2026/01/01 09:30 */ 方法注释格式 java 复制代码 /** * 方法描述 * * @param param 参数说明 * @return 返回值说明 */ 4.3 代码风格 Lombok简化代码:使用 @Data、@Slf4j、@Resource 等注解减少样板代码 构造器注入:通过 @Resource 进行依赖注入 统一返回格式:所有Controller方法返回 Result<T> 统一异常处理:通过 @RestControllerAdvice 全局捕获异常 ScopedValue:使用JDK 21的ScopedValue替代ThreadLocal,用于线程间上下文传递 虚拟线程:日志保存、消息处理等使用虚拟线程异步执行 链式调用:LogBus、TaskBus、MqBus支持链式API调用 接口驱动:LogBusInterface、TaskBusInterface、BaseMqHandle、StorageService均通过接口定义,业务层实现 4.4 设计规范 单一职责:每个模块专注单一功能领域(缓存、日志、消息队列等) 开闭原则:通过接口(LogBusInterface、TaskBusInterface、BaseMqHandle)支持扩展,无需修改框架代码 依赖倒置:高层模块通过接口依赖低层实现,如StorageService接口抽象文件存储和S3存储 按需加载:通过ImportSelector实现模块按需自动装配,引入依赖即生效 总线模式:LogBus、TaskBus、MqBus统一采用总线模式,通过Spring容器获取所有接口实现 4.5 安全规范 XSS防护:@IgnoreXss 注解标记不需要XSS过滤的字段,Jackson的String反序列化器自动过滤XSS 数据脱敏:@Mask 注解在JSON序列化阶段自动脱敏敏感数据 SQL监控:MyBatis拦截器记录慢查询和SQL日志 参数验证:使用 @Valid 注解进行参数校验,全局异常处理器统一处理校验失败 五、项目依赖设计 5.1 核心框架依赖 依赖 版本 用途 Spring Boot 4.0.6 应用框架 Spring Framework 7.0.7 核心框架 Spring AMQP 4.0.3 RabbitMQ集成 Spring Data BOM 2025.1.5 Spring Data版本管理 Jakarta Servlet 6.1.0 Servlet规范 5.2 数据访问依赖 依赖 版本 用途 MyBatis 4.0.1 ORM框架 MyBatis-Plus 3.5.16 ORM增强工具 Druid 1.2.28 数据库连接池 MySQL Connector 9.7.0 MySQL驱动 Elasticsearch Client 9.2.8 Elasticsearch客户端 5.3 工具库依赖 依赖 版本 用途 Lombok 1.18.46 代码简化 MapStruct 1.6.3 对象映射 FastJSON2 2.0.60 JSON处理 Jackson 3.1.2 JSON序列化/反序列化 Commons Lang3 3.20.0 通用工具 Commons IO 2.22.0 IO工具 Commons Text 1.15.0 文本处理 5.4 扩展工具依赖 依赖 版本 用途 BouncyCastle 1.84 加密库 OSHI 6.12.0 系统监控 ip2region 3.3.7 IP地址定位 java-jwt 4.5.1 JWT令牌 Caffeine 3.2.3 本地缓存 AWS S3 SDK 2.42.41 S3对象存储 5.5 办公工具依赖 依赖 版本 用途 Fesod Sheet 2.0.1-incubating Excel处理 PDFBox 3.0.7 PDF处理 5.6 文档相关依赖 依赖 版本 用途 Knife4j 4.5.0 API文档增强 Swagger Annotations 2.2.48 OpenAPI注解 SpringDoc OpenAPI 3.0.3 OpenAPI文档生成 5.7 任务调度依赖 依赖 版本 用途 XXL-JOB 3.4.0 分布式任务调度 5.8 监控依赖 依赖 版本 用途 Spring Boot Admin 4.0.4 应用监控 5.9 其他工具依赖 依赖 版本 用途 Velocity 2.4.1 模板引擎 Easy Captcha 1.6.2 验证码生成 Jsoup 1.22.2 HTML解析 UserAgentUtils 1.21 浏览器标识解析 Pinyin4j 2.5.1 拼音转换 Thumbnailator 0.4.21 图片压缩 ZXing 3.5.4 二维码/条形码 mmseg4j 1.10.0 中文分词 5.10 POM继承链 #mq6cndsgvkegjsqo1x9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#ccc;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mq6cndsgvkegjsqo1x9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mq6cndsgvkegjsqo1x9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mq6cndsgvkegjsqo1x9 .error-icon{fill:#a44141;}#mq6cndsgvkegjsqo1x9 .error-text{fill:#ddd;stroke:#ddd;}#mq6cndsgvkegjsqo1x9 .edge-thickness-normal{stroke-width:1px;}#mq6cndsgvkegjsqo1x9 .edge-thickness-thick{stroke-width:3.5px;}#mq6cndsgvkegjsqo1x9 .edge-pattern-solid{stroke-dasharray:0;}#mq6cndsgvkegjsqo1x9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mq6cndsgvkegjsqo1x9 .edge-pattern-dashed{stroke-dasharray:3;}#mq6cndsgvkegjsqo1x9 .edge-pattern-dotted{stroke-dasharray:2;}#mq6cndsgvkegjsqo1x9 .marker{fill:lightgrey;stroke:lightgrey;}#mq6cndsgvkegjsqo1x9 .marker.cross{stroke:lightgrey;}#mq6cndsgvkegjsqo1x9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mq6cndsgvkegjsqo1x9 p{margin:0;}#mq6cndsgvkegjsqo1x9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#ccc;}#mq6cndsgvkegjsqo1x9 .cluster-label text{fill:#F9FFFE;}#mq6cndsgvkegjsqo1x9 .cluster-label span{color:#F9FFFE;}#mq6cndsgvkegjsqo1x9 .cluster-label span p{background-color:transparent;}#mq6cndsgvkegjsqo1x9 .label text,#mq6cndsgvkegjsqo1x9 span{fill:#ccc;color:#ccc;}#mq6cndsgvkegjsqo1x9 .node rect,#mq6cndsgvkegjsqo1x9 .node circle,#mq6cndsgvkegjsqo1x9 .node ellipse,#mq6cndsgvkegjsqo1x9 .node polygon,#mq6cndsgvkegjsqo1x9 .node path{fill:#1f2020;stroke:#ccc;stroke-width:1px;}#mq6cndsgvkegjsqo1x9 .rough-node .label text,#mq6cndsgvkegjsqo1x9 .node .label text,#mq6cndsgvkegjsqo1x9 .image-shape .label,#mq6cndsgvkegjsqo1x9 .icon-shape .label{text-anchor:middle;}#mq6cndsgvkegjsqo1x9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mq6cndsgvkegjsqo1x9 .rough-node .label,#mq6cndsgvkegjsqo1x9 .node .label,#mq6cndsgvkegjsqo1x9 .image-shape .label,#mq6cndsgvkegjsqo1x9 .icon-shape .label{text-align:center;}#mq6cndsgvkegjsqo1x9 .node.clickable{cursor:pointer;}#mq6cndsgvkegjsqo1x9 .root .anchor path{fill:lightgrey!important;stroke-width:0;stroke:lightgrey;}#mq6cndsgvkegjsqo1x9 .arrowheadPath{fill:lightgrey;}#mq6cndsgvkegjsqo1x9 .edgePath .path{stroke:lightgrey;stroke-width:2.0px;}#mq6cndsgvkegjsqo1x9 .flowchart-link{stroke:lightgrey;fill:none;}#mq6cndsgvkegjsqo1x9 .edgeLabel{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgvkegjsqo1x9 .edgeLabel p{background-color:hsl(0, 0%, 34.4117647059%);}#mq6cndsgvkegjsqo1x9 .edgeLabel rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgvkegjsqo1x9 .labelBkg{background-color:rgba(87.75, 87.75, 87.75, 0.5);}#mq6cndsgvkegjsqo1x9 .cluster rect{fill:hsl(180, 1.5873015873%, 28.3529411765%);stroke:rgba(255, 255, 255, 0.25);stroke-width:1px;}#mq6cndsgvkegjsqo1x9 .cluster text{fill:#F9FFFE;}#mq6cndsgvkegjsqo1x9 .cluster span{color:#F9FFFE;}#mq6cndsgvkegjsqo1x9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(20, 1.5873015873%, 12.3529411765%);border:1px solid rgba(255, 255, 255, 0.25);border-radius:2px;pointer-events:none;z-index:100;}#mq6cndsgvkegjsqo1x9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#ccc;}#mq6cndsgvkegjsqo1x9 rect.text{fill:none;stroke-width:0;}#mq6cndsgvkegjsqo1x9 .icon-shape,#mq6cndsgvkegjsqo1x9 .image-shape{background-color:hsl(0, 0%, 34.4117647059%);text-align:center;}#mq6cndsgvkegjsqo1x9 .icon-shape p,#mq6cndsgvkegjsqo1x9 .image-shape p{background-color:hsl(0, 0%, 34.4117647059%);padding:2px;}#mq6cndsgvkegjsqo1x9 .icon-shape rect,#mq6cndsgvkegjsqo1x9 .image-shape rect{opacity:0.5;background-color:hsl(0, 0%, 34.4117647059%);fill:hsl(0, 0%, 34.4117647059%);}#mq6cndsgvkegjsqo1x9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mq6cndsgvkegjsqo1x9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mq6cndsgvkegjsqo1x9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}管理管理管理管理管理管理管理管理管理管理管理管理管理管理管理管理管理管理管理管理管理spring-boot-starter-parent4.0.6xtools-parent5.0.0xtools-parent-boot5.0.0xtools-boot5.0.0Spring Framework 7.0.7Jackson 3.1.2Spring AMQP 4.0.3Elasticsearch 9.2.8MySQL 9.7.0Lettuce 6.8.2RabbitMQ 5.27.1Tomcat 11.0.21FastJSON2 2.0.60BouncyCastle 1.84OSHI 6.12.0MapStruct 1.6.3Velocity 2.4.1S3 SDK 2.42.41ip2region 3.3.7MyBatis-Plus 3.5.16MyBatis 4.0.1Druid 1.2.28Knife4j 4.5.0XXL-JOB 3.4.0Spring Boot Admin 4.0.4六、技术选型说明 6.1 JDK 25 LTS版本:JDK 25是长期支持版本,提供长期稳定的安全更新 虚拟线程(Virtual Threads):项目大量使用虚拟线程进行异步操作,如日志保存、消息处理,大幅简化并发编程 ScopedValue:替代传统的ThreadLocal,用于线程间上下文传递(LogTrack、CommonHolder),性能更优且更安全 Record模式匹配:枚举类型使用record定义,支持简洁的模式匹配语法 Switch表达式:全局异常处理器等场景使用增强的switch表达式 文本块和String模板:日志格式化等场景使用文本块提升可读性 6.2 Spring Boot 4.0.6 Spring Framework版本:7.0.7,提供最新的核心功能 Jakarta EE 11:全面支持Jakarta EE 11规范(Jakarta Servlet 6.1.0) 自动配置:所有模块基于Spring Boot自动配置机制,引入依赖即生效 Actuator:内置应用监控端点 嵌入式容器:Tomcat 11.0.21 6.3 MyBatis-Plus 3.5.16 简化CRUD:通过BaseMapper提供通用增删改查 分页插件:内置分页拦截器,配合QueryUtils实现分页查询 代码生成:配合xtools-app-gen模块实现代码生成 SQL解析:通过mybatis-plus-jsqlparser支持SQL解析和优化 支持MyBatis版本:4.0.1 6.4 Elasticsearch 9.2.8 Spring Data Elasticsearch:通过Spring Data BOM 2025.1.5管理 全文搜索:用于日志检索和全文查询 高性能:基于Lucene的分布式搜索引擎 EsUtils:封装ES的GET/POST操作 EsQueryUtils:封装常用查询条件(matchPhrase、wildcard、timeRange) 6.5 Redis Spring Data Redis:通过Spring Boot 4.0.6管理(Lettuce 6.8.2客户端) RedisService:封装String、Hash、分布式锁等操作 FastJSON2序列化:使用FastJSON2进行Redis值的序列化/反序列化 分布式锁:基于RedisTemplate的setIfAbsent + Lua脚本实现 6.6 RabbitMQ Spring AMQP:4.0.3版本,提供RabbitMQ集成 RabbitMQ Client:5.27.1版本 消息总线:通过MqBus统一消息推送接口 消息编解码:MqMessageUtils提供消息的打包/解包 6.7 其他重要技术选型 技术 版本 选型原因 Jackson 3.1.2 Spring Boot默认JSON库(tools.jackson包),用于HTTP响应序列化 FastJSON2 2.0.60 高性能JSON库,用于Redis序列化和内部数据处理 Knife4j 4.5.0 增强Swagger UI,提供更友好的API文档界面 XXL-JOB 3.4.0 轻量级分布式任务调度平台 Druid 1.2.28 阿里巴巴数据库连接池,内置SQL监控和防火墙 ip2region 3.3.7 离线IP地址定位库,无需网络请求 BouncyCastle 1.84 Java加密扩展库,支持SM2/SM3等国密算法 OSHI 6.12.0 跨平台系统信息监控库 S3 SDK 2.42.41 AWS官方S3客户端,支持所有S3兼容存储 Spring Boot Admin 4.0.4 开源应用监控管理平台 文档版本:v1.0 编写日期:2026-06-09 项目版本:5.0.0 父POM版本:xtools-parent-boot:5.0.0 顶级父POM:xtools-parent:5.0.0 JDK版本:25 维护团队:xujun.org