Files
workutils/项目目录结构说明.md
T
2026-06-09 09:41:30 +08:00

360 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 项目目录结构说明
> **项目名称**: 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/
├── WorkUtilsApplication.java # 应用启动入口
├── system/ # 系统框架层(平台规范定义 + 共享基础设施)
│ ├── config/
│ │ └── WorkUtilsProperties.java # 全局配置属性类
│ ├── support/ # 共享基础设施
│ │ ├── ConsoleHelper.java # 控制台交互工具类
│ │ ├── FileOperationService.java# 文件操作服务(读取/扫描/写入/路径管理)
│ │ └── OutputService.java # 输出服务(CSV/Excel)
│ ├── tool/ # Tool 基础契约
│ │ └── Tool.java # 工具基础接口(Plugin 继承此接口)
│ └── plugin/ # 插件化框架
│ ├── Plugin.java # 插件接口(扩展 Tool,增加生命周期)
│ ├── PluginDescriptor.java # 插件描述符(id/name/version/description/dependencies)
│ ├── PluginContext.java # 插件运行时上下文
│ ├── PluginManager.java # 插件管理器(生命周期 + 注册 + 主菜单 + 命令分发)
│ └── PluginState.java # 插件状态枚举(UNLOADED/LOADED/ACTIVE/DISABLED/ERROR)
└── biz/ # 业务插件层(各模块是独立 Plugin)
├── batch/ # 批量处理插件
│ └── BatchTool.java # 批量检查入口(实现 Plugin)
├── git/ # Git 操作插件
│ ├── GitTool.java # Git 插件入口(实现 Plugin)
│ └── service/ # 服务实现层
│ ├── GitService.java # Git 服务接口
│ ├── GitServiceImpl.java # Git 服务实现
│ ├── config/
│ │ └── GitOptimizationConfig.java # Git 性能优化配置
│ ├── model/
│ │ └── GitCommand.java # Git 命令传输对象
│ └── internal/ # 内部实现(不对外暴露)
│ ├── GitCommandController.java # Git 命令控制器(异步/中断)
│ ├── GitCommandExecutor.java # Git 命令执行器(核心)
│ ├── GitRepositoryManager.java # Git 仓库管理器
│ ├── GitResultCache.java # Git 结果缓存管理器
│ └── strategy/ # 策略模式实现
│ ├── GitCommandStrategy.java # 策略接口
│ ├── GitStrategyFactory.java # 策略工厂
│ ├── CheckBranchChangesStrategy.java
│ └── CheckoutAndPullStrategy.java
├── mybatisexport/ # MyBatis SQL导出插件
│ ├── MyBatisExportTool.java # SQL 导出入口(实现 Plugin)
│ └── service/
│ ├── MyBatisExportService.java # SQL 导出服务
│ └── model/
│ └── MybatisTag.java # MyBatis 标签数据对象
├── mybatisgenerator/ # MyBatis逆向工程插件
│ ├── MyBatisGeneratorTool.java # 逆向工程入口(实现 Plugin)
│ └── service/generator/
│ ├── MyBatisGeneratorService.java # 逆向工程服务
│ ├── CustomCommentGenerator.java # 自定义注释生成器
│ ├── LombokPlugin.java # Lombok 插件(@Data)
│ └── SelectiveOnlyPlugin.java # 只保留 Selective 方法插件
└── scanner/ # 扫描插件
├── ScannerTool.java # 扫描工具入口(实现 Plugin)
└── service/ # 服务实现层
├── ScannerService.java # 扫描服务
└── config/
└── ScanConfig.java # 扫描配置
```
---
## 三、核心文件详解
### 3.1 入口层
#### `WorkUtilsApplication.java`
- **作用**: Spring Boot 应用启动类,实现 `CommandLineRunner`
- **功能**:
- 支持交互式菜单模式(无参数启动),委托 `PluginManager.runMainMenu()`
- 支持命令行模式,通过 `PluginManager.getPluginByCommand()` 按命令名分发
- 不依赖任何具体业务 Service,完全解耦
---
### 3.2 系统框架层(`system/`)
#### 3.2.1 插件化框架(`system/plugin/`)
| 文件 | 作用 |
|------|------|
| `Plugin.java` | **插件接口**,继承 `Tool`,增加生命周期方法 `onLoad(PluginContext)` / `onUnload()`,`getId()`/`getName()` 默认委托给 `PluginDescriptor` |
| `PluginDescriptor.java` | 插件描述符(不可变),包含 `id`、`name`、`version`、`description`、`dependencies`,通过 Builder 模式构建 |
| `PluginContext.java` | 插件运行时上下文,提供 `PluginManager` 引用和跨插件共享属性 |
| `PluginManager.java` | **插件管理器**(`@Component`),负责:生命周期管理(load/enable/disable)、注册发现(按 id/command 查找)、启用过滤(白名单/黑名单)、主菜单交互循环、命令行分发 |
| `PluginState.java` | 插件状态枚举:`UNLOADED` → `LOADED` → `ACTIVE` / `DISABLED` / `ERROR` |
#### 3.2.2 Tool 基础契约(`system/tool/`)
#### `Tool.java`
- **作用**: 工具基础接口,定义 `getId()`、`getName()`、`getMenuOptions()`、`execute()`、`handleChoice()`、`getCommandName()`、`executeCommand()` 等方法
- **关系**: `Plugin` 继承 `Tool`,biz 模块直接实现 `Plugin`
#### 3.2.3 共享基础设施(`system/support/`)
| 文件 | 作用 |
|------|------|
| `ConsoleHelper.java` | 控制台交互工具类(静态方法),统一控制台 I/O |
| `FileOperationService.java` | 文件操作服务,提供文件读取、扫描、写入、项目路径管理等基础能力 |
| `OutputService.java` | 输出服务,负责将数据输出为 CSV(OpenCSV)或 Excel(EasyExcel)格式 |
#### 3.2.4 全局配置(`system/config/`)
| 文件 | 作用 |
|------|------|
| `WorkUtilsProperties.java` | 全局配置属性类(`@ConfigurationProperties`),管理路径、工具启用/禁用(`ToolsConfig`) |
---
### 3.3 业务插件层(`biz/`)
> **架构约定**: 每个 biz 模块的 Tool 类放在模块根目录,实现 `Plugin` 接口(继承自 `Tool`)。通过静态 `PluginDescriptor` 声明插件元数据(id/name/version/description)。所有服务实现及附属文件收在 `service/` 子包下,内部细节用 `internal/` 隔离。
#### 3.3.1 扫描插件(`biz/scanner/`)
| 文件 | 作用 |
|------|------|
| `ScannerTool.java` | 扫描插件入口(实现 Plugin),版本 `1.0.0`,负责菜单交互,委托 ScannerService 执行业务逻辑 |
| `service/ScannerService.java` | 扫描服务,支持关键词扫描、Redis Key 扫描、Dubbo 接口扫描三种类型,支持并发多项目扫描 |
| `service/config/ScanConfig.java` | 扫描配置,定义文件扩展名、排除目录、最大文件大小等参数 |
#### 3.3.2a MyBatis SQL导出插件(`biz/mybatisexport/`)
| 文件 | 作用 |
|------|------|
| `MyBatisExportTool.java` | SQL 导出插件入口(实现 Plugin),版本 `1.0.0`,负责菜单交互 |
| `service/MyBatisExportService.java` | SQL 导出核心服务,从 XML 文件中提取 select/insert/update/delete 标签 |
| `service/model/MybatisTag.java` | MyBatis 标签数据对象 |
#### 3.3.2b MyBatis逆向工程插件(`biz/mybatisgenerator/`)
| 文件 | 作用 |
|------|------|
| `MyBatisGeneratorTool.java` | 逆向工程插件入口(实现 Plugin),版本 `1.0.0` |
| `service/generator/MyBatisGeneratorService.java` | MyBatis 逆向工程服务 |
| `service/generator/CustomCommentGenerator.java` | 自定义注释生成器 |
| `service/generator/LombokPlugin.java` | Lombok 插件(@Data) |
| `service/generator/SelectiveOnlyPlugin.java` | 只保留 Selective 方法插件 |
#### 3.3.3 Git 插件(`biz/git/`)
| 文件 | 作用 |
|------|------|
| `GitTool.java` | Git 插件入口(实现 Plugin),版本 `1.0.0` |
| `service/GitService.java` | Git 服务接口 |
| `service/GitServiceImpl.java` | Git 服务实现 |
| `service/config/GitOptimizationConfig.java` | Git 性能优化配置 |
| `service/model/GitCommand.java` | Git 命令传输对象 |
| `service/internal/GitCommandExecutor.java` | **核心执行器**,跨平台 git 命令执行 |
| `service/internal/GitCommandController.java` | Git 命令控制器(异步/中断) |
| `service/internal/GitRepositoryManager.java` | Git 仓库管理器 |
| `service/internal/GitResultCache.java` | Git 结果缓存管理器 |
| `service/internal/strategy/*` | 策略模式实现 |
#### 3.3.4 批量插件(`biz/batch/`)
| 文件 | 作用 |
|------|------|
| `BatchTool.java` | 批量处理插件入口(实现 Plugin),版本 `1.0.0`,一键执行多种检查 |
---
## 四、资源配置文件(`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个项目 |
---
## 五、设计模式与架构特点
| 模式/特点 | 应用位置 | 说明 |
|-----------|---------|------|
| **插件架构** | `Plugin` + `PluginManager` + `PluginDescriptor` | 每个 biz 模块作为独立 Plugin,声明版本、描述,PluginManager 统一管理生命周期(load/enable/disable),可插拔扩展 |
| **策略模式** | `Tool` / `Plugin` 接口 + 各 biz 实现 | 各插件通过实现 Plugin 接口注册到 PluginManager,支持交互和命令行双模式 |
| **策略模式** | `GitCommandStrategy` + 各 Strategy 实现 | Git 命令执行策略,`GitStrategyFactory` 管理注册 |
| **工厂模式** | `PluginManager`、`GitStrategyFactory` | Spring 自动发现和注入 Bean |
| **命令模式** | `GitCommand` + `GitCommandController` | 封装 Git 命令的异步执行、中断、跳过 |
| **缓存模式** | `GitResultCache` | 缓存 Git 查询结果,减少重复命令执行 |
| **并发处理** | `GitCommandExecutor`、`ScannerService` | 线程池并发执行 Git 命令和多项目扫描 |
| **过滤器模式** | `MyBatisExportService` 内部类 | `SqlFilter` 接口实现表名/关键字/标签ID 过滤 |
| **模板回调** | `FileOperationService.scanFilesRecursively` | 使用 `SimpleFileVisitor` 实现文件遍历回调 |
| **分层架构** | `system/` vs `biz/` | system 定义平台契约与共享基础设施,biz 实现具体插件 |
| **内部隔离** | `biz/*/service/internal/` | 内部实现类用 `internal/` 隔离,不对外暴露 |
| **生命周期管理** | `Plugin.onLoad()` / `Plugin.onUnload()` | 插件加载/卸载回调,PluginContext 传递运行时上下文 |
---
## 六、依赖关系图
```
WorkUtilsApplication (入口)
├── 交互模式 → PluginManager.runMainMenu()
│ └── PluginManager.getEnabledPlugins()
│ ├── ScannerTool ────────────→ ScannerService
│ ├── MyBatisExportTool ──────→ MyBatisExportService
│ ├── MyBatisGeneratorTool ───→ MyBatisGeneratorService
│ ├── GitTool ────────────────→ GitService → GitStrategyFactory
│ └── BatchTool ──────────────→ ScannerService + MyBatisExportService
│
└── 命令行模式 → PluginManager.getPluginByCommand(command)
├── "scan" → ScannerTool.executeCommand(args)
├── "sql" → MyBatisExportTool.executeCommand(args)
├── "batch" → BatchTool.executeCommand(args)
└── "git" → GitTool.executeCommand(args)
(启动类不依赖任何具体业务 Service)
插件加载链路:
PluginManager.init()
├── 遍历 Spring 中所有 Plugin Bean
├── 依次调用 plugin.onLoad(PluginContext)
├── 按 ToolsConfig 过滤启用/禁用
└── 构建 pluginByIdMap / pluginByCommandMap / pluginStates
核心依赖链:
ScannerService → FileOperationService + OutputService
MyBatisExportService → FileOperationService + OutputService
GitService → FileOperationService + GitCommandExecutor
OutputService → FileOperationService + WorkUtilsProperties
FileOperationService → WorkUtilsProperties
```
---
## 七、问题与改进建议
### 7.1 已知问题
| 问题 | 位置 | 说明 |
|------|------|------|
| 配置文件硬编码 | `mybatis-generator.properties` | 包含明文密码 |
| 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. **统一 fastjson 版本**,建议只保留 2.0.57
2. **将数据库密码移到外部配置文件**或使用环境变量
3. **更新 `项目说明.md`** 使其与实际技术栈一致
4. **增加单元测试**,目前无测试代码
---
## 八、插件化架构设计
### 8.1 核心概念
```
┌──────────────────────────────────────────────────────┐
│ PluginManager │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────┐ │
│ │ 生命周期管理 │ │ 注册与发现 │ │ 菜单/命令 │ │
│ │ load/unload │ │ id/command │ │ 分发 │ │
│ └─────────────┘ └──────────────┘ └────────────┘ │
│ │
│ pluginByIdMap pluginByCommandMap pluginStates │
└──────────────────────┬───────────────────────────────┘
│ onLoad(PluginContext)
┌──────────────┼──────────────┬──────────────┐
▼ ▼ ▼ ▼
ScannerTool MyBatisExport MyBatisGen GitTool BatchTool
[v1.0.0] [v1.0.0] [v1.0.0] [v1.0.0] [v1.0.0]
```
### 8.2 接口层次
```
Tool (system/tool/) ← 基础契约:getId/getName/getMenuOptions/execute/...
↑
Plugin (system/plugin/) ← 扩展契约:+getDescriptor/onLoad/onUnload
↑
各 biz 模块 ← 具体实现:@Component + PluginDescriptor
```
### 8.3 插件描述符(PluginDescriptor)
每个插件通过静态 `PluginDescriptor` 声明自身元数据:
| 字段 | 说明 | 示例 |
|------|------|------|
| `id` | 全局唯一标识 | `"scan"`, `"mybatisexport"` |
| `name` | 菜单显示名称 | `"扫描功能"` |
| `version` | 语义化版本 | `"1.0.0"` |
| `description` | 功能简述 | `"关键词/Redis/Dubbo扫描工具"` |
| `dependencies` | 依赖的插件 ID(预留) | `[]` |
### 8.4 插件状态机
```
UNLOADED ──load──▶ LOADED ──enable──▶ ACTIVE ──disable──▶ DISABLED
▲ │ │ │
│ │ error │ error │
│ ▼ ▼ │
└──────────────── ERROR ◀──────────── ERROR ◀─────────────┘
unload ↻ UNLOADED
```
### 8.5 后续插件化方向
当前已完成插件化基础框架搭建,后续可进一步实现:
1. **SPI 自动发现** — 通过 `META-INF/services` 或 Spring Factories 自动发现外部 jar 中的 Plugin 实现
2. **独立打包** — 每个 biz 模块打成独立 jar,`PluginManager` 动态加载
3. **热加载** — 基于自定义 ClassLoader 实现插件的动态加载/卸载/更新
4. **依赖注入隔离** — 每个插件使用独立 Spring 子容器(`ApplicationContext`),避免 Bean 冲突
5. **插件市场** — 插件仓库 + 版本管理 + 远程下载