From ecdfb1f1a1a4c1b0142aed103514c5a699c08494 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E5=AE=B6=E8=AE=AD?= Date: Mon, 8 Jun 2026 17:28:22 +0800 Subject: [PATCH] =?UTF-8?q?=E8=8F=9C=E5=8D=95=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../git/menu/GitMenu.java} | 7 +- .../mybatis/menu/MyBatisGeneratorMenu.java} | 7 +- .../mybatis/menu/MyBatisMenu.java} | 7 +- .../output/menu/BatchMenu.java} | 7 +- .../scanner/menu/ScanMenu.java} | 10 +- 项目目录结构说明.md | 284 ++++++++++++++++++ 6 files changed, 304 insertions(+), 18 deletions(-) rename src/main/java/com/example/workutils/{menu/handler/GitHealthHandler.java => biz/git/menu/GitMenu.java} (96%) rename src/main/java/com/example/workutils/{menu/handler/MyBatisGeneratorHandler.java => biz/mybatis/menu/MyBatisGeneratorMenu.java} (96%) rename src/main/java/com/example/workutils/{menu/handler/MyBatisHandler.java => biz/mybatis/menu/MyBatisMenu.java} (94%) rename src/main/java/com/example/workutils/{menu/handler/BatchHandler.java => biz/output/menu/BatchMenu.java} (96%) rename src/main/java/com/example/workutils/{menu/handler/ScanHandler.java => biz/scanner/menu/ScanMenu.java} (89%) create mode 100644 项目目录结构说明.md diff --git a/src/main/java/com/example/workutils/menu/handler/GitHealthHandler.java b/src/main/java/com/example/workutils/biz/git/menu/GitMenu.java similarity index 96% rename from src/main/java/com/example/workutils/menu/handler/GitHealthHandler.java rename to src/main/java/com/example/workutils/biz/git/menu/GitMenu.java index 3aefb8c..951b864 100644 --- a/src/main/java/com/example/workutils/menu/handler/GitHealthHandler.java +++ b/src/main/java/com/example/workutils/biz/git/menu/GitMenu.java @@ -1,4 +1,4 @@ -package com.example.workutils.menu.handler; +package com.example.workutils.biz.git.menu; import com.example.workutils.biz.git.service.GitService; import com.example.workutils.biz.git.util.GitCommandExecutor; @@ -13,12 +13,13 @@ import java.util.Scanner; import java.util.stream.Collectors; /** - * Git仓库健康检测工具 + * Git仓库健康检测菜单 + * 仅负责菜单展示和用户交互,业务逻辑委托给GitService */ @Slf4j @Component @RequiredArgsConstructor -public class GitHealthHandler extends AbstractTool { +public class GitMenu extends AbstractTool { private static final String[] MENU_OPTIONS = { "1. 检测所有仓库健康状态", diff --git a/src/main/java/com/example/workutils/menu/handler/MyBatisGeneratorHandler.java b/src/main/java/com/example/workutils/biz/mybatis/menu/MyBatisGeneratorMenu.java similarity index 96% rename from src/main/java/com/example/workutils/menu/handler/MyBatisGeneratorHandler.java rename to src/main/java/com/example/workutils/biz/mybatis/menu/MyBatisGeneratorMenu.java index c9f07ce..2010d76 100644 --- a/src/main/java/com/example/workutils/menu/handler/MyBatisGeneratorHandler.java +++ b/src/main/java/com/example/workutils/biz/mybatis/menu/MyBatisGeneratorMenu.java @@ -1,4 +1,4 @@ -package com.example.workutils.menu.handler; +package com.example.workutils.biz.mybatis.menu; import com.example.workutils.biz.mybatis.generator.MyBatisGeneratorService; import com.example.workutils.tool.AbstractTool; @@ -11,12 +11,13 @@ import java.util.List; import java.util.Scanner; /** - * MyBatis逆向工程工具 + * MyBatis逆向工程菜单 + * 仅负责菜单展示和用户交互,业务逻辑委托给MyBatisGeneratorService */ @Slf4j @Component @RequiredArgsConstructor -public class MyBatisGeneratorHandler extends AbstractTool { +public class MyBatisGeneratorMenu extends AbstractTool { private static final String[] MENU_OPTIONS = { "1. 根据表名生成(单表)", diff --git a/src/main/java/com/example/workutils/menu/handler/MyBatisHandler.java b/src/main/java/com/example/workutils/biz/mybatis/menu/MyBatisMenu.java similarity index 94% rename from src/main/java/com/example/workutils/menu/handler/MyBatisHandler.java rename to src/main/java/com/example/workutils/biz/mybatis/menu/MyBatisMenu.java index a72e358..15ffaa8 100644 --- a/src/main/java/com/example/workutils/menu/handler/MyBatisHandler.java +++ b/src/main/java/com/example/workutils/biz/mybatis/menu/MyBatisMenu.java @@ -1,4 +1,4 @@ -package com.example.workutils.menu.handler; +package com.example.workutils.biz.mybatis.menu; import com.example.workutils.biz.mybatis.export.MyBatisExportService; import com.example.workutils.tool.AbstractTool; @@ -10,12 +10,13 @@ import java.util.Arrays; import java.util.Scanner; /** - * MyBatis导出功能工具 + * MyBatis SQL导出菜单 + * 仅负责菜单展示和用户交互,业务逻辑委托给MyBatisExportService */ @Slf4j @Component @RequiredArgsConstructor -public class MyBatisHandler extends AbstractTool { +public class MyBatisMenu extends AbstractTool { private static final String[] MENU_OPTIONS = { "1. 导出所有SQL", diff --git a/src/main/java/com/example/workutils/menu/handler/BatchHandler.java b/src/main/java/com/example/workutils/biz/output/menu/BatchMenu.java similarity index 96% rename from src/main/java/com/example/workutils/menu/handler/BatchHandler.java rename to src/main/java/com/example/workutils/biz/output/menu/BatchMenu.java index 6cf1a92..5cbc66d 100644 --- a/src/main/java/com/example/workutils/menu/handler/BatchHandler.java +++ b/src/main/java/com/example/workutils/biz/output/menu/BatchMenu.java @@ -1,4 +1,4 @@ -package com.example.workutils.menu.handler; +package com.example.workutils.biz.output.menu; import com.example.workutils.biz.mybatis.export.MyBatisExportService; import com.example.workutils.biz.scanner.service.ScanService; @@ -12,12 +12,13 @@ import java.util.List; import java.util.Scanner; /** - * 批量处理功能工具 + * 批量处理菜单 + * 仅负责菜单展示和用户交互,业务逻辑委托给各Service */ @Slf4j @Component @RequiredArgsConstructor -public class BatchHandler extends AbstractTool { +public class BatchMenu extends AbstractTool { @FunctionalInterface public interface ExceptionRunnable { diff --git a/src/main/java/com/example/workutils/menu/handler/ScanHandler.java b/src/main/java/com/example/workutils/biz/scanner/menu/ScanMenu.java similarity index 89% rename from src/main/java/com/example/workutils/menu/handler/ScanHandler.java rename to src/main/java/com/example/workutils/biz/scanner/menu/ScanMenu.java index cf5bb9f..3923999 100644 --- a/src/main/java/com/example/workutils/menu/handler/ScanHandler.java +++ b/src/main/java/com/example/workutils/biz/scanner/menu/ScanMenu.java @@ -1,4 +1,4 @@ -package com.example.workutils.menu.handler; +package com.example.workutils.biz.scanner.menu; import com.example.workutils.biz.scanner.service.ScanService; import com.example.workutils.tool.AbstractTool; @@ -9,12 +9,13 @@ import org.springframework.stereotype.Component; import java.util.Scanner; /** - * 扫描功能工具 + * 扫描功能菜单 + * 仅负责菜单展示和用户交互,业务逻辑委托给ScanService */ @Slf4j @Component @RequiredArgsConstructor -public class ScanHandler extends AbstractTool { +public class ScanMenu extends AbstractTool { private static final String[] MENU_OPTIONS = { "1. 关键词扫描", @@ -50,9 +51,6 @@ public class ScanHandler extends AbstractTool { } } - /** - * 关键词扫描 - */ private void scanByKeyword(Scanner scanner) throws Exception { printMenuTitle("关键词扫描"); info("开始关键词扫描"); diff --git a/项目目录结构说明.md b/项目目录结构说明.md new file mode 100644 index 0000000..7ebeb92 --- /dev/null +++ b/项目目录结构说明.md @@ -0,0 +1,284 @@ +# 项目目录结构说明 + +> **项目名称**: workutils +> **技术栈**: Spring Boot 2.7.18 + Java 8 + Maven +> **项目类型**: Java 工作工具集项目(金融科技 FinTech 开发和维护工具集) + +--- + +## 一、项目顶层目录 + +``` +workutils/ +├── export/ # 导出文件目录(运行结果输出) +├── logs/ # 日志文件目录 +├── src/ # 源代码目录 +├── target/ # Maven 编译输出目录(67个.class文件) +├── generator.rar # MyBatis Generator 压缩包 +├── mvnw # Maven Wrapper(Unix/Mac) +├── mvnw.cmd # Maven Wrapper(Windows) +├── pom.xml # Maven 项目配置文件 +├── 项目说明.md # 项目概述文档 +└── 项目目录结构说明.md # 本文件 +``` + +| 文件/目录 | 说明 | +|-----------|------| +| `pom.xml` | Maven 项目配置,定义依赖(Spring Boot、MyBatis、EasyExcel、JGit、Dubbo、Redis Jedis、OpenCSV 等) | +| `mvnw` / `mvnw.cmd` | Maven Wrapper 脚本,无需本地安装 Maven 即可构建项目 | +| `generator.rar` | MyBatis Generator 相关资源压缩包 | +| `export/` | 运行工具后输出的结果文件目录,按日期分子目录(如 `20260608/`) | +| `logs/` | 应用程序日志输出目录 | +| `target/` | Maven 编译产物,包含编译后的 `.class` 文件和资源文件副本 | + +--- + +## 二、源码目录结构(`src/main/java/com/example/workutils/`) + +``` +src/main/java/com/example/workutils/ +├── WorkUtilsAppliction.java # 应用启动入口 +├── config/ +│ └── WorkUtilsProperties.java # 全局配置属性类 +├── tool/ +│ ├── Tool.java # 工具策略接口 +│ ├── AbstractTool.java # 工具基类(模板方法模式) +│ └── ToolRegistry.java # 工具注册中心 +├── menu/ +│ └── api/ +│ └── MenuRunner.java # 交互式菜单运行器 +└── biz/ + ├── git/ # Git操作业务模块 + │ ├── config/ + │ │ └── GitOptimizationConfig.java # Git性能优化配置 + │ ├── menu/ + │ │ └── GitMenu.java # Git仓库健康检测菜单(仅交互逻辑) + │ ├── model/ + │ │ └── GitCommandDTO.java # Git命令传输对象 + │ ├── service/ + │ │ ├── GitCommandStrategy.java # Git命令策略接口 + │ │ ├── GitService.java # Git服务接口 + │ │ └── impl/ + │ │ ├── GitServiceImpl.java # Git服务实现 + │ │ ├── GitStrategyFactory.java # Git策略工厂 + │ │ └── strategy/ + │ │ ├── CheckBranchChangesStrategy.java # 检查分支变更策略 + │ │ └── CheckoutAndPullStrategy.java # 切换并拉取策略 + │ └── util/ + │ ├── GitCommandController.java # Git命令控制器(异步/中断) + │ ├── GitCommandExecutor.java # Git命令执行器(核心) + │ ├── GitRepositoryManager.java # Git仓库管理器 + │ └── GitResultCache.java # Git结果缓存管理器 + ├── mybatis/ # MyBatis业务模块 + │ ├── export/ + │ │ └── MyBatisExportService.java # MyBatis SQL导出服务 + │ ├── generator/ + │ │ ├── CustomCommentGenerator.java # 自定义注释生成器 + │ │ ├── LombokPlugin.java # Lombok插件(@Data) + │ │ ├── MyBatisGeneratorService.java # MyBatis逆向工程服务 + │ │ └── SelectiveOnlyPlugin.java # 只保留Selective方法插件 + │ ├── menu/ + │ │ ├── MyBatisMenu.java # MyBatis SQL导出菜单(仅交互逻辑) + │ │ └── MyBatisGeneratorMenu.java # MyBatis逆向工程菜单(仅交互逻辑) + │ ├── model/ + │ │ └── MybatisTagBO.java # MyBatis标签数据对象 + │ └── service/ + │ └── XMLMapperChecker.java # XML Mapper检查器(旧版,包路径异常) + ├── output/ + │ ├── OutputService.java # 输出服务(CSV/Excel) + │ └── menu/ + │ └── BatchMenu.java # 批量处理菜单(仅交互逻辑) + └── scanner/ # 扫描业务模块 + ├── config/ + │ └── ScanConfigBO.java # 扫描配置对象 + ├── menu/ + │ └── ScanMenu.java # 扫描功能菜单(仅交互逻辑) + └── service/ + ├── FileOperationService.java # 文件操作服务 + └── ScanService.java # 扫描服务 +``` + +--- + +## 三、核心文件详解 + +### 3.1 入口层 + +#### `WorkUtilsAppliction.java` +- **作用**: Spring Boot 应用启动类,实现 `CommandLineRunner` +- **功能**: + - 支持交互式菜单模式(无参数启动) + - 支持命令行模式(`sql`、`scan` 命令) + - 通过 `MenuRunner` 动态构建主菜单 + +#### `WorkUtilsProperties.java` +- **作用**: 全局配置属性类,绑定 `application.yml` 中 `workutils` 前缀的配置 +- **功能**: + - 管理基础目录、配置目录、导出目录路径 + - 提供带日期时间戳的导出文件路径生成 + - 管理工具启用/禁用白名单和黑名单 + +--- + +### 3.2 工具框架层(`tool/`) + +#### `Tool.java` +- **作用**: 工具策略接口,所有可插拔工具需实现此接口 +- **核心方法**: `getId()`、`getName()`、`getMenuOptions()`、`execute()` + +#### `AbstractTool.java` +- **作用**: 工具基类,使用模板方法模式 +- **功能**: 提供标准菜单交互循环(显示菜单→读取选择→处理选择→循环),子类只需实现 `handleChoice()` + +#### `ToolRegistry.java` +- **作用**: 工具注册中心,Spring 自动发现 `Tool` Bean +- **功能**: 根据配置过滤启用/禁用工具,支持白名单(enabled)和黑名单(disabled)模式 + +--- + +### 3.3 菜单层(`menu/`) + +#### `MenuRunner.java` +- **作用**: 交互式主菜单运行器 +- **功能**: 从 `ToolRegistry` 动态构建主菜单,无需硬编码 Menu 引用 + +> **重构说明**: 原先的 `menu/handler/` 下的 Handler 类已全部移除。菜单交互类已分散到各业务模块的 `menu/` 子包中,统一命名为 `XxxMenu`,仅负责菜单展示和用户交互,业务逻辑委托给对应 Service。 + +--- + +### 3.4 业务模块(`biz/`) + +#### 3.4.1 Git 操作模块(`biz/git/`) + +| 文件 | 作用 | +|------|------| +| `menu/GitMenu.java` | **Git 菜单类**(仅交互),显示菜单、接收用户输入、委托 GitService 执行业务逻辑 | +| `GitOptimizationConfig.java` | Git 性能优化配置类,管理超时、线程池、缓存、批处理、Fetch、网络等配置参数 | +| `GitCommandDTO.java` | Git 命令传输对象,定义命令类型枚举(CHECK_BRANCH_CHANGES、CHECKOUT_AND_PULL 等6种) | +| `GitService.java` | Git 服务接口,定义分支变更检查、切换拉取、健康检测、修复仓库等方法 | +| `GitCommandStrategy.java` | Git 命令策略接口,策略模式的核心接口 | +| `GitServiceImpl.java` | Git 服务实现,协调各策略执行,实现仓库健康检测和修复逻辑 | +| `GitStrategyFactory.java` | Git 策略工厂,注册和管理所有策略实现 | +| `CheckBranchChangesStrategy.java` | 分支变更检查策略实现,比较两个分支的差异 | +| `CheckoutAndPullStrategy.java` | 切换并拉取策略实现,批量切换分支并拉取最新代码 | +| `GitCommandExecutor.java` | **核心执行器**,封装原生 git 命令执行(支持 Windows/Linux),提供超时控制、并发线程池、命令批处理 | +| `GitCommandController.java` | Git 命令控制器,管理命令的异步执行、跳过、中断功能 | +| `GitRepositoryManager.java` | Git 仓库管理器,提供仓库发现、分支操作、批量操作等高级封装 | +| `GitResultCache.java` | Git 结果缓存管理器,缓存仓库信息/分支信息/提交ID,减少重复 git 命令 | + +#### 3.4.2 MyBatis 模块(`biz/mybatis/`) + +| 文件 | 作用 | +|------|------| +| `menu/MyBatisMenu.java` | **MyBatis SQL 导出菜单**(仅交互),显示导出选项、接收用户输入、委托 MyBatisExportService 执行 | +| `menu/MyBatisGeneratorMenu.java` | **MyBatis 逆向工程菜单**(仅交互),显示生成选项、接收用户输入、委托 MyBatisGeneratorService 执行 | +| `MyBatisExportService.java` | **MyBatis SQL 导出核心服务**,从 XML 文件中提取 select/insert/update/delete 标签,支持按表名、关键字、标签ID 过滤导出为 CSV | +| `XMLMapperChecker.java` | XML Mapper 检查器,检查 XML 文件格式是否正确(注意:此文件包路径为 `com.example.workutils.service`,与项目结构不一致) | +| `MybatisTagBO.java` | MyBatis 标签数据对象,封装 tagId、tagName、parameterType、resultMap、namespace 等信息 | +| `MyBatisGeneratorService.java` | MyBatis 逆向工程服务,根据数据库表生成 PO、Mapper 接口、XML 映射文件 | +| `CustomCommentGenerator.java` | 自定义注释生成器,生成简洁中文注释(字段备注、方法名中文说明) | +| `LombokPlugin.java` | Lombok 插件,为 PO 类添加 `@Data` 注解并禁用 getter/setter 方法生成 | +| `SelectiveOnlyPlugin.java` | 自定义插件,只保留 `insertSelective` 和 `updateByPrimaryKeySelective`,移除全字段版本 | + +#### 3.4.3 输出模块(`biz/output/`) + +| 文件 | 作用 | +|------|------| +| `menu/BatchMenu.java` | **批量处理菜单**(仅交互),显示批量检查选项、接收用户输入、委托各 Service 执行 | +| `OutputService.java` | 输出服务,负责将数据输出为 CSV(OpenCSV)或 Excel(EasyExcel)格式,支持单Sheet/多Sheet、追加写入等 | + +#### 3.4.4 扫描模块(`biz/scanner/`) + +| 文件 | 作用 | +|------|------| +| `menu/ScanMenu.java` | **扫描功能菜单**(仅交互),显示扫描选项、接收用户输入、委托 ScanService 执行 | +| `ScanConfigBO.java` | 扫描配置对象,定义文件扩展名、排除目录、最大文件大小等扫描参数 | +| `FileOperationService.java` | 文件操作服务,提供文件读取、扫描、写入、项目路径管理等基础能力 | +| `ScanService.java` | 扫描服务,支持关键词扫描、Redis Key 扫描、Dubbo 接口扫描三种类型,支持并发多项目扫描 | + +--- + +## 四、资源配置文件(`src/main/resources/`) + +``` +src/main/resources/ +├── application.yml # Spring Boot 主配置文件 +├── logback.xml # 日志框架配置 +├── mybatis-generator.xml # MyBatis Generator 配置文件 +├── mybatis-generator.properties # MyBatis Generator 数据库连接配置 +└── config/ + └── 代码仓库项目路径.txt # 要扫描的代码仓库路径列表(含状态标记) +``` + +| 文件 | 说明 | +|------|------| +| `application.yml` | 配置应用名、`workutils` 路径配置、工具启用/禁用、日志级别 | +| `logback.xml` | Logback 日志配置,控制台输出格式为 `HH:mm:ss.SSS [线程] 级别 Logger - 消息` | +| `mybatis-generator.xml` | MyBatis Generator 配置,引用自定义插件(LombokPlugin、SelectiveOnlyPlugin、CustomCommentGenerator),配置模型/Mapper/XML 生成路径 | +| `mybatis-generator.properties` | 数据库连接信息(MySQL),JDBC URL/用户名/密码/驱动路径,以及生成的包路径 | +| `代码仓库项目路径.txt` | 待扫描的代码仓库绝对路径列表,每行格式 `路径|状态`(NORMAL/CORRUPTED),共约72个项目 | + +--- + +## 五、设计模式与架构特点 + +| 模式/特点 | 应用位置 | 说明 | +|-----------|---------|------| +| **策略模式** | `Tool` + `AbstractTool` + Handler 实现 | 各工具通过实现 `Tool` 接口注册,可插拔扩展 | +| **模板方法模式** | `AbstractTool` | 定义菜单交互骨架,子类实现 `handleChoice()` | +| **策略模式** | `GitCommandStrategy` + 各 Strategy 实现 | Git 命令执行策略,`GitStrategyFactory` 管理注册 | +| **工厂模式** | `ToolRegistry`、`GitStrategyFactory` | 自动发现和注册 Bean | +| **命令模式** | `GitCommandDTO` + `GitCommandController` | 封装 Git 命令的异步执行、中断、跳过 | +| **缓存模式** | `GitResultCache` | 缓存 Git 查询结果,减少重复命令执行 | +| **并发处理** | `GitCommandExecutor`、`ScanService` | 线程池并发执行 Git 命令和多项目扫描 | +| **过滤器模式** | `MyBatisExportService` 内部类 | `SqlFilter` 接口实现表名/关键字/标签ID 过滤 | +| **模板回调** | `FileOperationService.scanFilesRecursively` | 使用 `SimpleFileVisitor` 实现文件遍历回调 | + +--- + +## 六、依赖关系图 + +``` +WorkUtilsAppliction (入口) + ├── MenuRunner (菜单系统) + │ └── ToolRegistry (工具注册) + │ ├── BatchMenu ──────────────→ ScanService + MyBatisExportService + │ ├── GitMenu ────────────────→ GitService + │ ├── MyBatisMenu ────────────→ MyBatisExportService + │ ├── MyBatisGeneratorMenu ───→ MyBatisGeneratorService + │ └── ScanMenu ───────────────→ ScanService + │ + └── 命令行模式 + ├── sql → MyBatisExportService + └── scan → ScanService + +核心依赖链: + MyBatisExportService → FileOperationService + OutputService + ScanService → FileOperationService + OutputService + GitServiceImpl → FileOperationService + GitCommandExecutor + OutputService → FileOperationService + WorkUtilsProperties + FileOperationService → WorkUtilsProperties +``` + +--- + +## 七、问题与改进建议 + +### 7.1 发现的问题 + +| 问题 | 位置 | 说明 | +|------|------|------| +| 包路径不一致 | `XMLMapperChecker.java` | 实际包路径 `com.example.workutils.service`,但位于 `biz/mybatis/service/` 目录下 | +| 未使用文件 | `XMLMapperChecker.java` | 代码中没有任何地方引用此类 | +| 配置文件硬编码 | `mybatis-generator.properties` | 包含明文密码 `1Qaz@4772` | +| pom.xml 重复依赖 | `fastjson` 1.2.83 和 2.0.57 | 两个版本的 fastjson 同时存在 | +| 项目说明版本不匹配 | `项目说明.md` | 描述为 Spring Boot 3.2.3 + Java 21,实际为 Spring Boot 2.7.18 + Java 8 | + +### 7.2 重构建议 + +1. **修复 `XMLMapperChecker` 包路径**,或将其删除(未被引用) +2. **统一 fastjson 版本**,建议只保留 2.0.57 +3. **将数据库密码移到外部配置文件**或使用环境变量 +4. **更新 `项目说明.md`** 使其与实际技术栈一致 +5. **考虑提取公共的 CSV 操作到 `OutputService`**,减少 `MyBatisExportService` 中的 CSV 相关代码 +6. **增加单元测试**,目前无测试代码